【问题标题】:How to convert XML to Hash in ruby?如何在 ruby​​ 中将 XML 转换为 Hash?
【发布时间】:2017-02-24 19:39:20
【问题描述】:

我有一个要转换为哈希的 XML 代码

   <meta_description><language id="1"></language><language id="2"></language></meta_description>
    <meta_keywords><language id="1"></language><language id="2"></language></meta_keywords>
    <meta_title><language id="1"></language><language id="2" ></language></meta_title>
    <link_rewrite><language id="1" >konsult-500-krtim</language><language id="2" >konsult-500-krtim</language></link_rewrite>
    <name><language id="1" >Konsult 500 kr/tim</language><language id="2" >Konsult 500 kr/tim</language></name>
    <description><language id="1" ></language><language id="2" ></language></description>
    <description_short><language id="1" ></language><language id="2" ></language></description_short>
    <available_now><language id="1" ></language><language id="2" ></language></available_now>
    <available_later><language id="1" ></language><language id="2" ></language></available_later>
    <associations>
    <categories nodeType="category" api="categories">
    <category>
    <id>2</id>
    </category>
    </categories>
    <images nodeType="image" api="images"/>
    <combinations nodeType="combination" api="combinations"/>
    <product_option_values nodeType="product_option_value" api="product_option_values"/>
    <product_features nodeType="product_feature" api="product_features"/>
    <tags nodeType="tag" api="tags"/>
    <stock_availables nodeType="stock_available" api="stock_availables">
    <stock_available>
    <id>111</id>
    <id_product_attribute>0</id_product_attribute>
    </stock_available>
    </stock_availables>
    <accessories nodeType="product" api="products"/>
    <product_bundle nodeType="product" api="products"/>
    </associations>

我想将此 xml 转换为 Hash 。 我试图找到将此 xml 转换为 h=Hash.new 的函数 我该怎么做?

【问题讨论】:

  • 对于初学者,您需要拥有有效的 HTML 才能使以下任何答案起作用。此 xml 有错误,您可以使用 tool like this 验证它
  • 这是您的示例的变体,error xml removed

标签: ruby-on-rails ruby xml hash


【解决方案1】:

您可以使用 ActiveSupport 的 Hash#from_xml 方法:

xml = File.open("data.xml").read # if your xml is in the 'data.xml' file
Hash.from_xml(xml)

【讨论】:

  • 如果您使用的是猴子修补 Hash 类的 Rails,则此方法有效。但是,它在纯红宝石中无法开箱即用。
【解决方案2】:

如果您使用的是 Rails,您可以使用上面提供的答案,否则您可以要求 ActiveSuppport gem:

require 'active_support/core_ext/hash'

xml = '<foo>bar</foo>'
hash = Hash.from_xml(xml)
=>{"foo"=>"bar"}

请注意,这仅适用于有效的 xml。参见 op 上的 cmets。另请注意,使用 id="1" 之类的元素属性不会以相同的方式转换回来,例如:

xml = %q(
  <root>
    <foo id="1"></foo>
    <bar id="2"></bar>
  </root>).strip

hash = Hash.from(xml)
=>{"root"=>{"foo"=>{"id"=>"1"}, "bar"=>{"id"=>"2"}}}

puts hash.to_xml
# will output
<?xml version="1.0" encoding="UTF-8"?>
<hash>
  <root>
    <foo>
      <id>1</id>
    </foo>
    <bar>
      <id>2</id>
    </bar>
  </root>
</hash>

【讨论】:

    【解决方案3】:

    使用 nokogiri 将 XML 响应解析为 ruby​​ 哈希。速度挺快的。

    require 'active_support/core_ext/hash'  #from_xml 
    require 'nokogiri'
    
    doc = Nokogiri::XML(response_body)
    Hash.from_xml(doc.to_s)
    

    【讨论】:

    • 这里为什么需要 Nokogiri?如果respons_body 是 xml 类型,则不需要。例如Hash.from_xml(HTTParty.get('https://www.w3schools.com/xml/note.xml').body) 工作正常。是的,我以HTTParty 为例,但它应该说明这一点。
    猜你喜欢
    • 1970-01-01
    • 2011-06-22
    • 2011-05-15
    • 2011-01-26
    • 2017-05-05
    • 2011-06-16
    • 2013-12-27
    • 2010-12-16
    • 2014-07-02
    相关资源
    最近更新 更多