如何仅检索未嵌套的元素?

时间:2018-02-14 16:38:42

标签: ruby nokogiri

我正在尝试解析一些XML内容,在本例中是一些产品:

<PRODUCTS>
  <PRODUCT>
    <NAME><![CDATA[Some name]]></NAME>
    <CATEGORIES>
      <CATEGORY>
        <NAME><![CDATA[Category 1]]></NAME>
      </CATEGORY>
      <CATEGORY>
        <NAME><![CDATA[Category 2]]></NAME>
      </CATEGORY>
    </CATEGORIES>
  </PRODUCT>
  <PRODUCT>
    <NAME><![CDATA[Some other name]]></NAME>
    <CATEGORIES>
      <CATEGORY>
        <NAME><![CDATA[Category 1]]></NAME>
      </CATEGORY>
      <CATEGORY>
        <NAME><![CDATA[Category 2]]></NAME>
      </CATEGORY>
    </CATEGORIES>
  </PRODUCT>
</PRODUCTS>

如果我将上述内容放入doc变量并在每个产品中调用NAME

doc.css("PRODUCT").each do |product|
  puts product.css("NAME").size # => 3
end

我还获得了每个产品的嵌套NAME元素。

如何只获取未嵌套的NAME?我知道product.at_css("NAME")只返回第一个元素,但我的问题不是如何获取第一个元素,而是如何获取未嵌套的元素。

3 个答案:

答案 0 :(得分:2)

您可以使用>仅选择NAME直接子女的PRODUCT元素:

doc.css("PRODUCT").each do |product|
  puts product.css("> NAME")
end

这将输出以下内容:

<NAME><![CDATA[Some name]]></NAME>
<NAME><![CDATA[Some other name]]></NAME>

答案 1 :(得分:0)

您可以使用以下

doc.css("PRODUCT").each do |product|
   puts product.css("NAME").first
end

答案 2 :(得分:0)

使用XPath

doc.xpath("PRODUCTS/PRODUCT").each do |product| 
  puts product.xpath("NAME").first
end
在这种情况下,

.xpath("NAME")仅返回直接后代。使用css子选择器可以实现相同的效果。

doc.css("PRODUCT").each do |product| 
  puts product.css("> NAME").first
end