如何将Nokogiri HTML节点转换为JSON



我输出HTML节点(Nokogiri::XML::Element <Nokogiri::XML::Node),看起来像这样:>

<prog>
  <prog_name>Barclay CTA Index</prog_name>
  <prog_id>9</prog_id>
</prog>

我想得到这样的哈希值:

{
    prog_name: "Barclay CTA Index"
    prog_id: 9
}

to_hash方法不工作:

[3] pry(main)> prog_element.to_hash
[]

试试这个:

Hash.from_xml(prog_element.to_xml).to_json

如果您的XML很简单,那么构建散列是很容易的:

require 'json'
require 'nokogiri'
xml = <<EOT
<prog>
  <prog_name>Barclay CTA Index</prog_name>
  <prog_id>9</prog_id>
</prog>
EOT
doc = Nokogiri::XML(xml)
prog_name = doc.at('prog_name').text
prog_id = doc.at('prog_id').text.to_i
hash = {
  prog_name: prog_name,
  prog_id: prog_id
}
hash # => {:prog_name=>"Barclay CTA Index", :prog_id=>9}
puts hash.to_json
# >> {"prog_name":"Barclay CTA Index","prog_id":9}

如果您的XML不是那么简单(这应该在示例中反映出来),那么它就有点复杂了:

require 'json'
require 'nokogiri'
xml = <<EOT
<xml>
  <prog>
    <prog_name>Barclay CTA Index</prog_name>
    <prog_id>9</prog_id>
  </prog>
  <prog>
    <prog_name>foo</prog_name>
    <prog_id>1</prog_id>
  </prog>
</xml>
EOT
doc = Nokogiri::XML(xml)
hash = {
  'prog' => []
}
doc.search('prog').each do |prog|
  prog_name = doc.at('prog_name').text
  prog_id = doc.at('prog_id').text.to_i
  hash['prog'] << {
    prog_name: prog_name,
    prog_id: prog_id
  }
end
hash
# => {"prog"=>
#      [{:prog_name=>"Barclay CTA Index", :prog_id=>9},
#       {:prog_name=>"Barclay CTA Index", :prog_id=>9}]}
puts hash.to_json
# >> {"prog":[{"prog_name":"Barclay CTA Index","prog_id":9},{"prog_name":"Barclay CTA Index","prog_id":9}]}

XML趋向于冗长,而JSON非常简洁,因此通常不需要将XML节点一对一地映射到JSON,从而允许我们挑选JSON的外观。如果XML非常大,并且包含大量不需要传递的数据,那么这是一个很大的优势。

如果你想要逐字转换XML,你可以利用其他gem或者使用Rails的from_xml,它可以在Active Support的Hash核心扩展中找到,但没有在那里记录。它在Active Support Hash文档中有记录:

require 'active_support/core_ext/hash/conversions'
require 'json'
xml = <<EOT
<xml>
  <prog>
    <prog_name>Barclay CTA Index</prog_name>
    <prog_id>9</prog_id>
  </prog>
  <prog>
    <prog_name>foo</prog_name>
    <prog_id>1</prog_id>
  </prog>
</xml>
EOT
hash = Hash.from_xml(xml)
# => {"xml"=>
#      {"prog"=>
#        [{"prog_name"=>"Barclay CTA Index", "prog_id"=>"9"},
#         {"prog_name"=>"foo", "prog_id"=>"1"}]}}
puts hash.to_json
# >> {"xml":{"prog":[{"prog_name":"Barclay CTA Index","prog_id":"9"},{"prog_name":"foo","prog_id":"1"}]}}

请注意,使用from_xml不会将prog_id值从字符串转换为整数,就像它们可能应该的那样,这意味着它们也将作为JSON序列化的字符串传递。此外,如果XML中有不需要的节点,它们将被传递到JSON中,使其膨胀并减慢传输速度,因此您需要决定是要在用户的浏览器还是接收端施加这种影响。

一旦您理解了XML和Nokogiri,使用Nokogiri将XML转换为哈希就不是那么困难了,掌握了这些知识是您工具箱中的一套很好的工具。依靠from_xml之类的东西是可以的,因为它很方便,但你需要权衡这些知识和做自定义事情的能力。操作和访问散列中的数据通常比直接使用Nokogiri这样的工具更糟糕,因此它的存在。

相关内容

  • 没有找到相关文章

最新更新