我需要将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>
看看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来完成同样的事情。