Nokogiri的Hpricot式“容器”方法?仅选择某些node_types

时间:2011-04-19 16:13:25

标签: ruby containers nokogiri hpricot

我正在使用带有Ruby的CSS选择器导航文档,但我在Hpricot中发现了一些css选择器错误,这些错误已在Nokogiri中修复,并且想要切换。

我遇到的一个问题是弄清楚如何获得所有“容器”(即不是文本节点)的孩子的数组。 Hpricot提供了开箱即用的容器方法功能。

所以在Hpricot我能做到:

children = doc.select('*')[0].containers

但是对于Nokogiri来说,似乎只能通过以下方式获得相同的功能(而且我不确定它是否以完全相同的方式运行):

children = doc.css('*')[0].children.to_a.keep_if {|x| x.type != Nokogiri::XML::Node::TEXT_NODE }

有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

为了澄清,您只想要子元素,而不是子文本节点?如果是这样,这里有三种技术:

require 'nokogiri'
doc = Nokogiri::XML "<r>no<a1><b1/></a1><a2>no<b2>hi</b2>mom</a2>no</r>"

# If the element is uniquely selectable via CSS
kids1 = doc.css('r > *')

# ...or if we assume you found an element and want only its children
some_node = doc.at('r')

# One way to do it
kids2 = some_node.children.grep(Nokogiri::XML::Element)

# A geekier-but-shorter-way
kids3 = some_node.xpath('*')

# Confirm that they're the same (converting the NodeSets to arrays)
p [ kids1.to_a == kids2, kids2 == kids3.to_a ]
#=> [true, true]

p kids1.map(&:name), kids2.map(&:name), kids3.map(&:name)
#=> ["a1", "a2"]
#=> ["a1", "a2"]
#=> ["a1", "a2"]