1

I am new to ruby and rails programming and I need to parse an xml file that I get as a response and store the station names in an array. A sample of the xml is as follows :

<Stations>
<Station>
<Code>HT</Code>
<Type>knooppuntIntercitystation</Type>
<Namen>
<Kort>Den Bosch</Kort>
<Middel>'s-Hertogenbosch</Middel>
<Lang>'s-Hertogenbosch</Lang>
</Namen>
<Land>NL</Land>
<UICCode>8400319</UICCode>
<Lat>51.69048</Lat>
<Lon>5.29362</Lon>
<Synoniemen>
<Synoniem>Hertogenbosch ('s)</Synoniem>
<Synoniem>Den Bosch</Synoniem>
</Synoniemen>
</Station>
<Station>
<Code>HTO</Code>
<Type>stoptreinstation</Type>
<Namen>
<Kort>Dn Bosch O</Kort>
<Middel>Hertogenbosch O.</Middel>
<Lang>'s-Hertogenbosch Oost</Lang>
</Namen>
<Land>NL</Land>
<UICCode>8400320</UICCode>
<Lat>51.700553894043</Lat>
<Lon>5.3183331489563</Lon>
<Synoniemen>
<Synoniem>Hertogenbosch Oost ('s)</Synoniem>
<Synoniem>Den Bosch Oost</Synoniem>
</Synoniemen>
</Station>
</Stations>

I need to get the Code and the Lang name in an array of hashes or just the lang name in an array.

How can I do that in ruby ? thanks in advance

1
  • I'd recommend searching for "ruby xml parser" and "parsing xml with ruby" plus variations on those. Please read "How to Ask" along with the linked pages. Commented Nov 16, 2016 at 17:24

2 Answers 2

2

you can use

hash = Hash.from_xml(xml)

Refrence doc:

http://apidock.com/rails/v4.0.2/Hash/from_xml/class

Sign up to request clarification or add additional context in comments.

2 Comments

Oh, never seen this one. Fortunately, I might add :)
@SergioTulentsev Sure, I get it. I'm just saying that this is not always the right solution.
1

Here's a solution which doesn't require Rails but a small gem (xml-simple) :

#  gem install xml-simple
require 'xmlsimple'

stations = XmlSimple.xml_in(xml, :ForceArray => ['Station', 'Synoniem'])

codes_and_langs = stations['Station'].map{|station| {:code => station["Code"], :lang => station.fetch("Namen",{})["Lang"]}}
puts codes_and_langs.inspect
#=> [{:code=>"HT", :lang=>"'s-Hertogenbosch"}, {:code=>"HTO", :lang=>"'s-Hertogenbosch Oost"}]

If you are using Rails or have Rails installed :

require 'active_support/core_ext/hash' # <- Use this line for non-Rails Ruby scripts.

hash            = Hash.from_xml(xml)
root_node       = hash["Stations"]     || {}
stations        = root_node["Station"] || []
codes_and_langs = stations.compact.map do |station|
  {
    :code       => station["Code"],
    :lang       => station.fetch('Namen',{})['Lang']
  }
end
puts codes_and_langs.inspect
#[{:code=>"HT", :lang=>"'s-Hertogenbosch"}, {:code=>"HTO", :lang=>"'s-Hertogenbosch Oost"}]

just_langs = stations.compact.map do |station|
  station.fetch('Namen',{})['Lang']
end

puts just_langs.inspect
# ["'s-Hertogenbosch", "'s-Hertogenbosch Oost"]

Hash#fetch is used to avoid an exception if "Namen" isn't defined.

Here's xml variable for both scripts :

xml="<Stations>
    <Station>
    <Code>HT</Code>
    <Type>knooppuntIntercitystation</Type>
    <Namen>
    <Kort>Den Bosch</Kort>
    <Middel>'s-Hertogenbosch</Middel>
    <Lang>'s-Hertogenbosch</Lang>
    </Namen>
    <Land>NL</Land>
    <UICCode>8400319</UICCode>
    <Lat>51.69048</Lat>
    <Lon>5.29362</Lon>
    <Synoniemen>
    <Synoniem>Hertogenbosch ('s)</Synoniem>
    <Synoniem>Den Bosch</Synoniem>
    </Synoniemen>
    </Station>
    <Station>
    <Code>HTO</Code>
    <Type>stoptreinstation</Type>
    <Namen>
    <Kort>Dn Bosch O</Kort>
    <Middel>Hertogenbosch O.</Middel>
    <Lang>'s-Hertogenbosch Oost</Lang>
    </Namen>
    <Land>NL</Land>
    <UICCode>8400320</UICCode>
    <Lat>51.700553894043</Lat>
    <Lon>5.3183331489563</Lon>
    <Synoniemen>
    <Synoniem>Hertogenbosch Oost ('s)</Synoniem>
    <Synoniem>Den Bosch Oost</Synoniem>
    </Synoniemen>
    </Station>
    </Stations>
    "

14 Comments

I have rails, so I was using your second suggestion but I get the following error "NoMethodError Exception: undefined method `[]' for nil:NilClass" . Sorry if I am sounding stupid but I am really new to this
The code works fine with the example you posted, maybe your bigger xml isn't formatted the same or has missing nodes. I'll update the code with a more robust solution.
The updated version should work with empty Station nodes.
Thanks! THis works. And something simpler, how about if I wanted instead of a hash just to make an array with the Long names?
thanks that works as well, and a final question if you can help me, how would i print the just_langs in my index.html.erb, since I am using rails and it is part of what I want to do.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.