2016-11-16 29 views
1

我是ruby和rails編程的新手,我需要解析一個我作爲響應獲得的xml文件,並將站名存儲在數組中。該XML的示例如下:xml到ruby中的數組

<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>

我需要獲得代碼和郎名散列的數組或只是郎名稱在數組中。

我該如何做到這一點在紅寶石? 由於事先

+0

我建議你搜索「紅寶石XML解析器」,並加上變化對那些「與紅寶石解析XML」。請閱讀「[問]」以及鏈接的頁面。 –

回答

1

這裏有一個解決方案,它不需要Rails的,但小寶石(XML的簡單):

# 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"}] 

如果您使用Rails或ha已經安裝了Rails:

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用於避免如果「Namen」未定義例外。

下面是這兩個腳本xml變量:

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> 
    " 
+0

我有導軌,所以我使用你的第二個建議,但我得到了以下錯誤「NoMethodError異常:未定義的方法'[]'爲零:NilClass」。對不起,如果我聽起來很愚蠢,但我真的很新 –

+0

該代碼適用於您發佈的示例,也許你更大的XML不是格式相同或缺少節點。我將用更強大的解決方案更新代碼。 –

+0

更新後的版本應與空站節點一起使用。 –

2

可以使用

hash = Hash.from_xml(xml) 

Refrence DOC:

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

+1

哦,從來沒有見過這個。幸運的是,我可能會添加:) –

+1

只有當您使用導軌時,這纔會起作用。 –

+0

@GowthamG:問題用rails標記,所以... –