【问题标题】:Parse XML to Ruby objects and create attribute methods dynamically?将 XML 解析为 Ruby 对象并动态创建属性方法?
【发布时间】:2013-04-07 22:29:58
【问题描述】:

我需要将 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>

【问题讨论】:

    标签: ruby xml xml-parsing nokogiri


    【解决方案1】:

    看看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 来完成相同的事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-18
      • 2017-10-14
      • 2013-06-11
      • 2017-07-27
      相关资源
      最近更新 更多