2011-04-19 44 views
1

我正在使用帶有Ruby的CSS選擇器瀏覽文檔,但是我發現Hpricot中一些在Nokogiri中修復的css選擇器錯誤,並且想要切換。Nokogiri的Hpricot風格「容器」方法?只選擇某個node_types

我遇到的一個問題是搞清楚如何獲取所有「容器」(即不是文本節點)的孩子的數組。 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 } 

有沒有更好的方法來做到這一點?

回答

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"] 
+0

這是非常好的,正是我所期待的。 我一定會使用較短的(geeky?:P)版本,非常乾淨。 – 2011-04-24 02:40:25