我希望这不是一个重复的问题。我花了很多时间寻找一个有效的解决方案,但我没有运气。我正在尝试做的是遍历每个xml节点并获取特定节点。为了达到这个目的,我使用的是Ruby,Nikogiri和xpath。
所以我有一个简单的xml文件,看起来像这个sitemap.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"
输出&gt;
http://www.stackoverflow.com/questions/ask1/
因此您可以看到它不会输出所有节点/标记。我已经尝试将代码放在for循环中,但它所做的只是重复相同的节点。知道如何获得我想要的输出:
所需的输出&gt;
http://www.stackoverflow.com/questions/ask1/
http://www.stackoverflow.com/questions/ask2/
http://www.stackoverflow.com/questions/ask3/
答案 0 :(得分:2)
您的文件不是有效的XML文档,因为it contains more than one root node。如果您inspect
docSM
变量的内容,您应该能够看到Nokogiri只解析了第一个<url>
,因为它是第一个根节点。
您需要包含更高级别节点中的所有<url>
以创建有效文档。即
<urls>
<url>...</url>
<url>...</url>
</urls>
答案 1 :(得分:2)
这很接近,但错过了一些小细节。 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
正如您所建议的那样,您将获得一个字符串,其中所有文本都已连接在一起,并且两者之间没有分隔符。
答案 2 :(得分:2)
您的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>]