2013-04-15 47 views
1

我需要解析一個XML文件到Ruby對象。將XML解析爲Ruby對象並動態創建屬性方法?

是否有讀取XML屬性這樣 report.system_slots.items返回項屬性的陣列的工具, 或report.system_slots.current_usage回「有空」?

是否可以與Nokogiri做到這一點?

<page Title="System Slots" H1="Property" H2="Value" __type__="2"> 
    <item Property="System Slot 1"> 
    <item Property="Name" Value="PCI1"/> 
    <item Property="Type" Value="PCI"/> 
    <item Property="Data Bus Width" Value="32 bits"/> 
    <item Property="Current Usage" Value="Available"/> 
    <item Property="Characteristics"> 
    <item Property="Vcc voltage supported" Value="3.3 V, 5.0 V"/> 
    <item Property="Shared" Value="No"/> 
    <item Property="PME Signal" Value="Yes"/> 
    <item Property="Support Hot Plug" Value="No"/> 
    <item Property="PCI slot supports SMBus signal" Value="Yes"/> 
    </item> 
</item> 

回答

6

看看Ox。它讀取XML並返回XML的合理Ruby對象傳真。

require 'ox' 

hash = {'foo' => { 'bar' => 'hello world'}} 

puts Ox.dump(hash) 

pp Ox.parse_obj(Ox.dump(hash)) 

傾倒到這IRB給我:

require 'ox' 

> hash = {'foo' => { 'bar' => 'hello world'}} 
{ 
    "foo" => { 
     "bar" => "hello world" 
    } 
} 

> puts Ox.dump(hash) 
<h> 
    <s>foo</s> 
    <h> 
    <s>bar</s> 
    <s>hello world</s> 
    </h> 
</h> 
nil 

> pp Ox.parse_obj(Ox.dump(hash)) 
{"foo"=>{"bar"=>"hello world"}} 
{ 
    "foo" => { 
     "bar" => "hello world" 
    } 
} 

這就是說,你的XML樣品斷裂,不會與OX工作。它工作與Nokogiri,雖然有錯誤報告,這將暗示你將無法正確解析DOM。

我的問題是,你爲什麼要將XML轉換爲對象?使用像Nokogiri這樣的解析器處理XML更容易。使用你的XML的一個固定的版本:

require 'nokogiri' 

xml = ' 
<xml> 
<page Title="System Slots" H1="Property" H2="Value" __type__="2"> 
    <item Property="System Slot 1"/> 
    <item Property="Name" Value="PCI1"/> 
    <item Property="Type" Value="PCI"/> 
    <item Property="Data Bus Width" Value="32 bits"/> 
    <item Property="Current Usage" Value="Available"/> 
    <item Property="Characteristics"> 
    <item Property="Vcc voltage supported" Value="3.3 V, 5.0 V"/> 
    <item Property="Shared" Value="No"/> 
    <item Property="PME Signal" Value="Yes"/> 
    <item Property="Support Hot Plug" Value="No"/> 
    <item Property="PCI slot supports SMBus signal" Value="Yes"/> 
    </item> 
</page> 
</xml>' 

doc = Nokogiri::XML(xml) 

page = doc.at('page') 
page['Title'] # => "System Slots" 
page.at('item[@Property="Current Usage"]')['Value'] # => "Available" 

item_properties = page.at('item[@Property="Characteristics"]') 
item_properties.at('item[@Property="PCI slot supports SMBus signal"]')['Value'] # => "Yes" 

解析一個大的XML文檔到內存中可以返回數組和散列仍然有被剝離開來訪問你想要的值的迷宮。使用Nokogiri,您可以輕鬆學習和閱讀CSS和XPath訪問器;我使用上面的CSS,但可以很容易地使用XPath來完成相同的事情。

+2

這裏是牛的Git回購: https://github.com/ohler55/ox –