doc.xpath( "/ExperimentCollection/Experiment/mzData/description/admin/sampleDescription/MeSH/@accession" )
Ничего не возвращает, потому что нет тега MeSH
. Вам необходимо заменить MeSH
на cvParam[@cvLabel=\"MeSH\"]
(читай: тег cvParam
, который имеет атрибут cvLabel
со значением MeSH
).
Как только вы исправите это, xpath
вернет коллекцию Nokogiri::XML::Attr
объектов. Вызвав текст этой коллекции, вы получите строковое значение первого элемента. Поскольку вам нужны все элементы, вы должны вместо этого использовать map(&:text)
(или map {|n| n.text}
в ruby 1.8.6), который будет возвращать массив, содержащий строковое значение каждого атрибута accession
(то есть ["D017209", "D019014"]
для примера XML- файл).
Так как вы, кажется, смущены, вот пояснение:
@ Бобби: Когда я сказал "xpath
вернет коллекцию Nokogiri::XML::Attr
объектов", я имел в виду именно это. Вы вызываете xpath
, а затем xpath
создает и возвращает коллекцию Attr
объектов. Я никоим образом не имел в виду, что вы должны вручную создавать любые Attr
объекты.
И когда я сказал, что вы должны использовать map
, я просто имел в виду, что вы должны вызвать map
для коллекции, возвращаемой xpath
(хотя вместо использования map
вы можете просто вызвать puts
с коллекцией как аргумент).
- Итак, вам нужно 1. исправить ваш xpath, как я описал.
- используйте
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