【问题标题】:Having trouble determining if element exists无法确定元素是否存在
【发布时间】:2015-03-08 03:40:49
【问题描述】:

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

【问题讨论】:

  • xml 中的第二项是什么?您使用的是哪个 xml 解析库?结果是预期的行为吗?
  • 不确定它是如何改变的,但帖子的主题最初是“Nokogiri:无法确定元素是否存在”。
  • @ChrisA。在这个网站上,我们尽量将标签放在标题之外; sawa 编辑了您的问题以更好地符合公认的标准。

标签: ruby xml nokogiri


【解决方案1】:

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

相反,您想使用 XPath 表达式仅查找 child &lt;name&gt; 元素。您可以通过明确地将其设为 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

【讨论】:

    猜你喜欢
    • 2011-05-14
    • 1970-01-01
    • 1970-01-01
    • 2018-08-03
    • 2016-02-07
    • 2021-12-26
    • 2015-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多