Reputation: 7038
I am trying to retrieve two elements both with nine responses from an xml file with Nokogiri. Retrieval itself isn't hard:
number = @doc.xpath('//Race/@RaceNumber').text
# => "123456789"
But it selects it as one string. And this is the other reduced for brevity:
name = @doc.css('NameRaceFull')
# => [#<Nokogiri::XML::Element:0x1775154 name="NameRaceFull" attributes=[#<Nokogiri::XML::Attr:0x1774448 name="StakesGroupId" value="346">]
My goal is to create a hash and so on for each number and name
{ 1 => "Greenland Australia Maribyrnong Trial Stakes" }
But with the retrieval pulling it all as a string, how would I get this to work?
My solution was to create two arrays and then do Hash[number.zip(name)]
, but if this is possible in one go, that would be great.
@doc.xpath('//Race/@RaceNumber').text.each do |name|
arr << name
end
# => NoMethodError: undefined method `each' for "123456789":String
The example part of the XML I am getting this from is this.
<Race RaceCode="5038498" CurrentRaceStage="Results" RaceNumber="1">
<NameRaceFull StakesGroupId="346">Greenland Australia Maribyrnong Trial Stakes</NameRaceFull>
Upvotes: 1
Views: 208
Reputation: 35443
Here's how I would solve it:
hash = Hash[doc.xpath('//Race').map{|race|
[race["RaceNumber"].to_i, race.xpath('NameRaceFull').text]
}]
The output hash:
{1=>"Foo", 2=>"Goo", 3=>"Hoo"}
The code works like this:
Race
items and iterate on them. Note that Ruby offers a variety of ways to convert items to hashes, and you can use any way you prefer. For example, Hash#[]
, Array#to_h
, Enumerable#inject
, etc.
Here's a complete code example with simplified XML for clarity:
#!/usr/bin/env ruby
require 'nokogiri'
xml=<<-qqq
<Races>
<Race RaceNumber="1"><NameRaceFull>Foo</NameRaceFull></Race>
<Race RaceNumber="2"><NameRaceFull>Goo</NameRaceFull></Race>
<Race RaceNumber="3"><NameRaceFull>Hoo</NameRaceFull></Race>
</Races>
qqq
doc=Nokogiri.parse(xml)
hash = Hash[doc.xpath('//Race').map{|race|
[race["RaceNumber"].to_i, race.xpath('NameRaceFull').text]
}]
p hash
Upvotes: 1