2

我使用 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

正如你所看到的,这正是我想要的,除了一件事:它读取的是产品而不是产品。

如何将我的搜索限制在产品范围内?回答时,请注意示例已简化。我希望该解决方案“擦除”产品知识(如果可能的话),因为它可能在所有情况下都有效。

4

3 回答 3

2

而不是

//*[not(*)] 

使用

(//product)[1]//*[not(*)] 

product这仅选择XML 文档中第一个元素下的“叶节点” 。

product对文档中的所有元素重复此操作。您可以通过以下方式获得他们的计数:

count(//product)
于 2013-03-31T16:13:56.253 回答
0

您可能只想:

product_data = product.xpath("*")

这都会找到产品的子元素。

于 2013-03-31T16:02:39.307 回答
0

答案是简单地添加一个.before //*[not(*)]

product_data = product.xpath(".//*[not(*)]")

这告诉 XPath 表达式从当前节点而不是根开始。

Novatchev 先生的回答虽然在技术上是正确的,但不会导致解析代码成为惯用的 Ruby。

于 2013-04-05T23:03:16.987 回答