[英]Using Nokogiri with XML files in Ruby
我有这个XML:
<Experiment>
<mzData version="1.05" accessionNumber="1635">
<description>
<admin>
<sampleName>Fas-induced and control Jurkat T-lymphocytes</sampleName>
<sampleDescription>
<cvParam cvLabel="MeSH" accession="D017209" name="apoptosis" />
<cvParam cvLabel="UNITY" accession="D2135" name="Jurkat cells" />
<cvParam cvLabel="MeSH" accession="D019014" name="Antigens, CD95" />
</sampleDescription>
</admin>
</description>
</mzData>
</Experiment>
</ExperimentCollection>
我也有以下代码:
require 'rubygems'
require 'nokogiri'
doc = Nokogiri::XML(File.open("my.xml"))
sampleName = doc.xpath( "/ExperimentCollection/Experiment/mzData/description/admin/sampleName" ).text
sampleDescription = doc.xpath( "/ExperimentCollection/Experiment/mzData/description/admin/sampleDescription/MeSH/@accession" ).text
puts sampleName + " " + sampleDescription
foo = sampleName + " " + sampleDescription
f = File.new("my.txt","w")
f.write(foo)
f.close()
该代码可以很好地sampleName
,但不能sampleName
accession
字母/数字。 我只是想抓住后,所有的字母/数字MeSH
- > accession
( D017209
和D019014
)。 为了使此工作有效,我必须在doc.xpath
命令中进行哪些更改?
doc.xpath( "/ExperimentCollection/Experiment/mzData/description/admin/sampleDescription/MeSH/@accession" )
不返回任何内容,因为没有标签MeSH
。 您需要用cvParam[@cvLabel=\\"MeSH\\"]
替换MeSH
(阅读:一个cvParam
标记,其属性cvLabel
的值为MeSH
)。
修复xpath
将返回Nokogiri::XML::Attr
对象的集合。 通过在该集合上调用文本,您将获得第一个元素的字符串值。 由于希望所有应改用元件的map(&:text)
(或map {|n| n.text}
在红宝石1.8.6),这将返回一个包含每个的字符串值的阵列accession
属性(即["D017209", "D019014"]
XML文件示例的["D017209", "D019014"]
。
由于您似乎很困惑,因此请进行以下说明:
@Bobby:当我说“ xpath
将返回Nokogiri::XML::Attr
对象的集合”时,我的意思就是那样。 您调用xpath
,然后xpath
创建并返回Attr
对象的集合。 我绝不是说您应该自己手动创建任何Attr
对象。
当我说您应该使用map
,我只是说您应该在xpath
返回的集合上调用map
(尽管您可以使用该集合作为参数来调用puts
,而不是使用map
)。
xpath
与固定的xpath一起使用以获取集合 换一种说法:
require 'rubygems'
require 'nokogiri'
doc = Nokogiri::XML(File.open("my.xml"))
common_prefix = "/ExperimentCollection/Experiment/mzData/description/admin"
sample_name = doc.xpath( common_prefix+"/sampleName" ).text
accessions = doc.xpath( common_prefix+
"/sampleDescription/cvParam[@cvLabel=\"MeSH\"]/@accession" )
puts sample_name
puts accessions
这是一种简单的方法,尽管这可能太聪明了,因为您可能还想做其他事情:
File.open("my.txt","w") do |f|
doc.xpath('//cvParam[@cvLabel="MeSH"]').each {|n| f << "#{n['name']} #{n['accession']}\n"}
end
您可能需要更具选择性的xpath语句。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.