我使用Ruby 1.9.3p385和Nokogiri来解析XML文件。不太确定我使用的是哪个xpath版本,但它确实响应v.1语法/函数,而不是v.2语法。
我有这个XML文件:
<root_tag>
<middle_tag>
<item_tag>
<headline_1>
<tag_1>Product title 1</tag_1>
</headline_1>
<headline_2>
<tag_2>Product attribute 1</tag_2>
</headline_2>
</item_tag>
<item_tag>
<headline_1>
<tag_1>Product title 2</tag_1>
</headline_1>
<headline_2>
<tag_2>Product attribute 2</tag_2>
</headline_2>
</item_tag>
</middle_tag>
</root_tag>
我想提取所有产品,为此我使用以下代码:
products = xml_file.xpath("/root_tag/middle_tag/item_tag/headline_1|/root_tag/middle_tag/item_tag/headline_2")
puts products.size # => 4
查看输出,使用:
products.each_with_index do |product, i|
puts "product #{i}:"
puts product
end
你得到这个:
product 0:
<headline_1>
<tag_1>Product title 1</tag_1>
</headline_1>
product 1:
<headline_2>
<tag_2>Product attribute 1</tag_2>
</headline_2>
product 2:
<headline_1>
<tag_1>Product title 2</tag_1>
</headline_1>
product 3:
<headline_2>
<tag_2>Product attribute 2</tag_2>
</headline_2>
我需要我的代码加入/合并所有匹配到相同的结果(所以产品。size应该是2)。最终输出应该像这样:
product 0:
<headline_1>
<tag_1>Product title 1</tag_1>
</headline_1>
<headline_2>
<tag_2>Product attribute 1</tag_2>
</headline_2>
product 1:
<headline_1>
<tag_1>Product title 2</tag_1>
</headline_1>
<headline_2>
<tag_2>Product attribute 2</tag_2>
</headline_2>
我在网上找遍了,但是所有的变化,例如:
products = xml_file.xpath("/root_tag/middle_tag/item_tag/*[self::headline_1|self::headline_2]")
似乎都输出相同的结果。
我是否遗漏了xpath中的重要内容,或者我是否忽略了某些内容?
XPath只知道普通序列,所以没有子序列之类的东西。您必须将每个"产品"包装到某个XML元素中。很高兴我们已经有了这样一个元素(<item_tag/>
),所以代码相当简单:
products = doc.xpath("(//item_tag")
products.each_with_index do |product, i|
puts "product #{i}:"
product.children.each do |line|
puts line
end
end
输出是(可能需要一些更多的格式化,但我不习惯ruby,不能帮助你):
product 0:
<headline_1>
<tag_1>Product title 1</tag_1>
</headline_1>
<headline_2>
<tag_2>Product attribute 1</tag_2>
</headline_2>
product 1:
<headline_1>
<tag_1>Product title 2</tag_1>
</headline_1>
<headline_2>
<tag_2>Product attribute 2</tag_2>
</headline_2>
要处理所有<headline_n/>
-标签,您还可以使用//*[starts-with(local-name(), 'headline')]
来使代码更灵活