I have this 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>
I also have the following code:
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()
The code grabs the sampleName just fine, but not the accession letters/numbers. I only want to grab all the letters/numbers after MeSH -> accession (D017209 and D019014). What do I have to change in the doc.xpath command to make this work?
Returns nothing because there is no tag
MeSH. You need to replaceMeSHwithcvParam[@cvLabel=\"MeSH\"](read: acvParamtag which has an attributecvLabelwith the valueMeSH).Once you fixed that
xpathwill return a collection ofNokogiri::XML::Attrobjects. By calling text on that collection you will get back the string value of the first element. Since you want all of the elements you should instead usemap(&:text)(ormap {|n| n.text}in ruby 1.8.6) which will return an array containing the string value of eachaccessionattribute (i.e.["D017209", "D019014"]for the example XML-file).Since you seem to be confused, here’s a clarification:
@Bobby: When I said “
xpathwill return a collection ofNokogiri::XML::Attrobjects”, I meant just that. You callxpathand thenxpathcreates and returns a collection ofAttrobjects. In no way did I mean that you should manually create anyAttrobjects yourself.And when I said you should use
map, I just meant you should callmapon the collection returned byxpath(though instead of usingmapyou can just callputswith the collection as an argument).xpathwith the fixed xpath to get a collectionIn other words: