繁体   English   中英

在Ruby中将Nokogiri与XML文件一起使用

[英]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 - > accessionD017209D019014 )。 为了使此工作有效,我必须在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 )。

  1. 因此,您需要做的是1.如我所述修复您的xpath。
  2. xpath与固定的xpath一起使用以获取集合
  3. 用看跌期权打印

换一种说法:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM