【问题标题】:Hpricot-style "container" method for Nokogiri? Select only certain node_typesNokogiri 的 Hpricot 式“容器”方法?仅选择某些 node_types
【发布时间】:2011-08-08 19:57:40
【问题描述】:

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

我遇到的一个问题是弄清楚如何获取所有作为“容器”(即不是文本节点)的子节点的数组。 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 }

有没有更好的方法来做到这一点?

【问题讨论】:

    标签: ruby containers nokogiri hpricot


    【解决方案1】:

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

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

    【讨论】:

    • 这很棒,正是我想要的。我肯定会使用更短的(极客?:P)版本,非常干净。
    猜你喜欢
    • 1970-01-01
    • 2011-02-22
    • 2017-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-10
    • 2019-04-18
    相关资源
    最近更新 更多