我使用Ruby 1.9.3p385, Nokogiri和xpath v.1。
在Stackoverflow上很棒的人的帮助下,我想出了这个xpath表达式:
products = xml_file.xpath("(/root_tag/middle_tag/item_tag")
分割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>
变成2个产物
我现在希望遍历每个产品并提取所有产品信息(通过提取其叶节点)。为此,我使用以下代码:
products.each do |product|
puts product #=> <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>
product_data = product.xpath("//*[not(*)]")
puts product_data #=> <tag_1>Product title 1</tag_1><tag_2>Product attribute 1</tag_2><tag_1>Product title 2</tag_1><tag_2>Product attribute 2</tag_2>
end
正如您所看到的,这正是我想要的,除了一件事:它读取产品而不是产品。
如何将搜索限制为只搜索产品?回答时,请注意这个例子是简化的。我更喜欢解决方案"擦除"产品知识(如果可能的话),因为这样它可能在所有情况下都有效。
代替:
//*[not(*)]
使用:
(//product)[1]//*[not(*)]
只选择XML文档中第一个product
元素下的"叶节点"。
对文档中的所有product
元素重复此操作。您可以通过以下命令获取它们的数量:
count(//product)
只需在//*[not(*)]
之前添加一个.
:
product_data = product.xpath(".//*[not(*)]")
这告诉XPath表达式从当前节点而不是根节点开始。
。Novatchev的回答虽然在技术上是正确的,但不会导致解析代码是惯用的Ruby。
你可能只是想:
product_data = product.xpath("*")
查找product的子元素