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

How to retrieve only elements that are not nested?

我正在尝试解析一些 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") returns 只是第一个元素,但我的问题不是如何获取第一个元素,而是如何获取未嵌套的元素。

您只能使用 > 到 select NAME 元素,这些元素是 PRODUCT:

的直接子元素
doc.css("PRODUCT").each do |product|
  puts product.css("> NAME")
end

这将输出以下内容:

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

您可以使用以下

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

使用XPath:

doc.xpath("PRODUCTS/PRODUCT").each do |product| 
  puts product.xpath("NAME").first
end

.xpath("NAME") 在这种情况下 returns 仅直系后代。使用 css 子选择器可以达到相同的效果。

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