无法确定元素是否存在

Having trouble determining if element exists

我有一个 xml 文档,其中充满了嵌套的 item 节点。在大多数情况下,每个 item 都有一个 name 元素。我想检查 item 是否有 name 元素,如果 return 不存在则检查默认名称。

<item>
  <name>Item 1</name>
</item>
<item>
    <items>
        <item>
          <name>Child Item 1</name>
        </item>
        <item>
          <name>Child Item 2</name>
        </item>
    </items>
</item>

当我向 node.at('name') 询问没有 name 元素的节点时,它会从树下方的子节点中选择下一个节点。在上面的例子中,如果我在第二个 item 上询问 at('name'),我会得到 "Child Item 1".

问题是您正在使用 at(),它可以接受 CSS 选择器或 XPath 表达式,并试图猜测您给它的是哪个。在这种情况下,它认为 name 是一个 CSS 选择器,它是一个后代选择器,选择当前节点下方任何位置的 name 个元素。

相反,您想使用 XPath 表达式仅查找 child <name> 元素。您可以通过使其明确成为 XPath 表达式来做到这一点:

node.at('./name')

或者你可以使用at_xpath的方法来搞清楚:

node.at_xpath('name')

这是一个简单的工作示例:

require 'nokogiri'
doc = Nokogiri.XML '<r>
  <item id="a">
    <name>Item 1</name>
  </item>
  <item id="b">
      <items>
          <item id="c">
            <name>Child Item 1</name>
          </item>
          <item id="d">
            <name>Child Item 2</name>
          </item>
      </items>
  </item>
</r>'

doc.css('item').each do |item|
  name = item.at_xpath('name')
  name = name ? name.text : "DEFAULT"
  puts "#{item['id']} -- #{name}"
end

#=> a -- Item 1
#=> b -- DEFAULT
#=> c -- Child Item 1
#=> d -- Child Item 2