<root>
  <channel>
    <one>example</one>
    <two>example2</two>
  </channel>
  <channel>
    <one>example</one>
  </channel>
</root>

在第二个节点中,我没有 <two> 节点。如果我使用这个:root.channel.two 显然我会收到错误“方法丢失”。如何检查以避免此错误?我将使用的条件语句是什么?

最佳答案

技术 1:挽救任何错误

require 'nokogiri'
d = Nokogiri.XML("<foo><bar /></foo>")
bad = d.root.bar            #=> undefined method `bar' for #<...> (NoMethodError)
d.slop!
yay = d.root.bar            #=> #<... name="bar">
bad = d.root.xxx            #=> undefined method `xxx' for #<...> (NoMethodError)
yay = d.root.xxx rescue nil #=> nil

技巧 2:跳前先看(又名不要使用 Slop)
%w[ bar xxx ].each do |node_name|
  if n = d.root.at_xpath(node_name)
    puts "Yay! #{n}"
  else
    puts "No node named #{node_name}"
  end
end
#=> Yay! <bar/>
#=> No node named xxx

使用 slop 时,(no-slop)代码 some_node.at_xpath("foo")some_node.foo 相同,不同之处在于它在不存在具有该名称的子节点时返回 nil。事实上,Slop 的实现只是调用 xpath 作为元素名称:如果它找到很多元素,你就会得到那个 Nodeset;如果它只找到一个元素,它会给你;如果没有找到任何元素,则会引发 NoMethodError 。重要的部分如下所示:
def method_missing( name )
  list = xpath(name)
  if list.empty?
    super                 # NoMethodError unless someone else handles this
  elsif list.length == 1
    list.first            # Since we only found one element, return that
  else
    list                  # ...otherwise return the whole list
  end
end

以下是 Nokogiri 文件对 Slop 的描述(在脚注中):



一般来说,XPath 比 slop 遍历更强大、更快。例如,如果要遍历每个 <two> 节点,可以执行以下操作:
d.xpath('/root/channel/two').each do |two|
  # This will only find nodes that exist
end

如果您描述了您最终真正需要做什么,我们可以帮助您编写更好的代码。在我个人看来,Slop 通常是一种不太有效的遍历文档的方法。

关于ruby - 测试子节点是否存在(没有得到 NoMethodError),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8511586/

10-08 22:59