无法确定元素是否存在

时间:2015-03-08 03:40:49

标签: ruby xml nokogiri

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

<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元素的节点时,它会从树下面的子节点中选择下一个节点。在上述情况下,如果我在第二个at('name')上询问item,我会"Child Item 1"

1 个答案:

答案 0 :(得分:0)

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

相反,您希望使用XPath表达式仅查找 <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