将XML解析为Ruby对象并动态创建属性方法?

aza*_*ytc 1 ruby xml nokogiri xml-parsing

我需要将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>
Run Code Online (Sandbox Code Playgroud)

the*_*Man 6

看看.它读取XML并返回XML的合理Ruby对象传真.

require 'ox'

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

puts Ox.dump(hash)

pp Ox.parse_obj(Ox.dump(hash))
Run Code Online (Sandbox Code Playgroud)

将其转入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"
    }
}
Run Code Online (Sandbox Code Playgroud)

也就是说,您的XML示例已损坏,无法与OX一起使用.它WILL与引入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"
Run Code Online (Sandbox Code Playgroud)

将一个大的XML文档解析到内存中可以返回一个迷宫般的数组和散列,仍然需要剥离以访问所需的值.使用Nokogiri,你有CSS和XPath访问器,易于学习和阅读; 我使用上面的CSS,但很容易使用XPath来完成相同的事情.