【问题标题】:Looping through each xml node循环遍历每个 xml 节点
【发布时间】:2014-06-23 10:06:54
【问题描述】:

我希望这不是一个重复的问题。我花了很多时间四处寻找可行的解决方案,但我没有运气。我要做的是遍历每个 xml 节点并取出一个特定的节点。为了实现这一点,我使用了 Ruby、Nikogiri 和 xpath。

所以我有一个看起来像这个 sitemap.xml 的简单 xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<url>
  <loc>http://www.stackoverflow.com/questions/ask1/</loc>
</url>
<url>
  <loc>http://www.stackoverflow.com/questions/ask2/</loc>
</url>
<url>
  <loc>http://www.stackoverflow.com/questions/ask3/</loc>
</url>

所以我试图提取每个 .这是我的代码:

siteMap = 'sitemap.xml'
sm = File.open(siteMap)
docSM = Nokogiri::XML(sm)

siteMapLinks = docSM.xpath("/url/loc").inner_text
print siteMapLinks.to_s + "\n"

输出>

http://www.stackoverflow.com/questions/ask1/

如您所见,它不会输出所有节点/标签。我尝试将代码放在 for 循环中,但它所做的只是重复同一个节点。知道如何获得我想要的输出:

期望的输出>

http://www.stackoverflow.com/questions/ask1/
http://www.stackoverflow.com/questions/ask2/
http://www.stackoverflow.com/questions/ask3/

【问题讨论】:

    标签: ruby xml xpath nokogiri


    【解决方案1】:

    这很接近,但遗漏了一些小细节。 Nokogiri 会解析您的 XML,直到第一个顶级标签关闭,因此如果您希望它解析所有 URL,您将需要一些封装标签,如

    <?xml version="1.0" encoding="UTF-8"?>
    <urls>
      <url>
        <loc>http://www.stackoverflow.com/questions/ask1/</loc>
      </url>
      <url>
        <loc>http://www.stackoverflow.com/questions/ask2/</loc>
      </url>
      <url>
        <loc>http://www.stackoverflow.com/questions/ask3/</loc>
      </url>
    </urls>
    

    现在您可以使用

    查询您的文档
    docSM.xpath("//url/loc").each do |node|
      puts node.inner_text
    end
    

    如果你这样做了

    docSM.xpath("//url/loc").inner_text
    

    按照您的建议,您将得到一个字符串,其中所有文本连接在一起,中间没有分隔符。

    【讨论】:

    • 其实你可以将其解析为 Nokogiri DocumentFragment 而无需插入根标签。
    【解决方案2】:

    您的文件不是有效的 XML 文档,因为it contains more than one root node。如果您 inspect docSM 变量的内容,您应该能够看到 Nokogiri 只解析了第一个 &lt;url&gt;,因为它是第一个根节点。

    您需要将所有&lt;url&gt;s 包含在更高级别的节点中才能创建有效的文档。即

    <urls>
      <url>...</url>
      <url>...</url>
    </urls>
    

    【讨论】:

      【解决方案3】:

      您的 XML 无效。您可以通过查看文档的 errors 方法来测试:

      require 'nokogiri'
      
      doc = Nokogiri::XML(<<EOT)
      <url>
        <loc>http://www.stackoverflow.com/questions/ask1/</loc>
      </url>
      <url>
        <loc>http://www.stackoverflow.com/questions/ask2/</loc>
      </url>
      EOT
      
      doc.errors # => [#<Nokogiri::XML::SyntaxError: Extra content at the end of the document>]
      

      【讨论】:

        猜你喜欢
        • 2021-06-22
        • 2011-09-11
        • 1970-01-01
        • 1970-01-01
        • 2014-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多