ruby – 如何在Nokogiri XML DocumentFragment中迭代特定名称的子节点?

前端之家收集整理的这篇文章主要介绍了ruby – 如何在Nokogiri XML DocumentFragment中迭代特定名称的子节点?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在名为“string”的字符串中给出这个 XML
  1. <Guide>
  2. <Master>
  3. <Part>12345</Part>
  4. <Sub>
  5. <Name>A</Name>
  6. </Sub>
  7. <Sub>
  8. <Name>B</Name>
  9. </Sub>
  10. </Master>
  11. <Master>
  12. <Part>XYZABC</Part>
  13. <Sub>
  14. <Name>A</Name>
  15. </Sub>
  16. <Sub>
  17. <Name>C</Name>
  18. </Sub>
  19. </Master>
  20. </Guide>

这行代码

  1. bgdoc = Nokogiri::XML::DocumentFragment.parse(xstring.to_xml)

我想遍历名为“Part”的所有节点.

我尝试了以下方法

  1. bgdoc.xpath("//Part").each do |node|

和:

  1. bgdoc.children.each do |node|
  2. next unless node.name=="Part"

但那没用.

解决方法

问题是将XML解析为片段会返回一个部分XML文档,即DocumentFragment,它没有root:
  1. 1.9.2-p290 :002 > doc = Nokogiri::XML::DocumentFragment.parse('<a><b>foo</b></a>').root
  2. NoMethodError: undefined method `root' for #<Nokogiri::XML::DocumentFragment:0x00000100b34448>
  3. from (irb):2
  4. from /Users/greg/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'

而完整的XML文档确实有一个根:

  1. 1.9.2-p290 :003 > doc = Nokogiri::XML('<a><b>foo</b></a>').root
  2. => #<Nokogiri::XML::Element:0x8058b350 name="a" children=[#<Nokogiri::XML::Element:0x80587b10 name="b" children=[#<Nokogiri::XML::Text:0x80587818 "foo">]>]>

默认情况下,Nokogiri将使用类似// Path的XPath从文档的根目录进行搜索

  1. 1.9.2-p290 :004 > doc = Nokogiri::XML('<a><Path>foo</Path></a>').search('//Path')
  2. => [#<Nokogiri::XML::Element:0x8055465c name="Path" children=[#<Nokogiri::XML::Text:0x805543c8 "foo">]>]

但由于缺少root,片段失败了:

  1. 1.9.2-p290 :005 > doc = Nokogiri::XML::DocumentFragment.parse('<a><Path>foo</Path></a>').search('//Path')
  2. => []

诀窍是告诉Nokogiri在处理片段时要查看的位置.使用相对搜索通配符:

  1. 1.9.2-p290 :006 > doc = Nokogiri::XML::DocumentFragment.parse('<a><Path>foo</Path></a>').search('.//Path')
  2. => [#<Nokogiri::XML::Element:0x8053c69c name="Path" children=[#<Nokogiri::XML::Text:0x8053c46c "foo">]>]

要么

  1. 1.9.2-p290 :007 > doc = Nokogiri::XML::DocumentFragment.parse('<a><Path>foo</Path></a>').search('*//Path')
  2. => [#<Nokogiri::XML::Element:0x8052a208 name="Path" children=[#<Nokogiri::XML::Text:0x80529fec "foo">]>]

猜你在找的Ruby相关文章