删除指定节点后的所有节点

时间:2011-09-29 15:08:47

标签: ruby nokogiri

我正在从网址抓取一个div文本,并希望删除具有backtotop类的段落下的所有内容。我在stackoverflow上看到了一个遍历代码片段看起来很有希望,但我无法弄清楚如何将它合并到一起,所以@el只包含div中第一个p.backtotop的所有内容。

我的代码:

@doc = Nokogiri::HTML(open(url))
@el = @doc.css("div")[0]
end

traverse snippet:

doc = Nokogiri::HTML(code)
stop_node = doc.css("p.backtotop")
doc.traverse do |node|
break if node == stop_node
# else, do whatever, e.g. `puts node.name`
end

2 个答案:

答案 0 :(得分:4)

  1. 找到你想要的div。
  2. 找到您想要的“停止”项目,然后找到以下所有兄弟姐妹。
  3. 删除它们。
  4. 例如:

    <body>
      <div id="a">
        <h2>My Section</h2>
        <p class="backtotop">Back to Top</p>
        <p>More Content</p>
        <p>Even More Content</p>
      </div>
    </body>
    
    require 'nokogiri'
    doc = Nokogiri::HTML(my_html)
    div = doc.at('#a')
    div.at('.backtotop').xpath('following-sibling::*').remove
    puts div
    #=> <div id="a">
    #=>     <h2>My Section</h2>
    #=>     <p class="backtotop">Back to Top</p>
    #=>     
    #=>     
    #=>   </div>
    

    这是一个更复杂的例子,其中backtotop项可能不在div的根部:

    <body>
      <div id="b">
        <h2>Another Section</h2>
        <section>
          <p class="backtotop">Back to Top</p>
          <p>More Content</p>
         </section>
        <p>Even More Content</p>
      </div>
    </body>
    
    require 'nokogiri'
    doc = Nokogiri::HTML(my_html)
    div = doc.at('#b')
    n   = div.at('.backtotop')
    until n==div
      n.xpath('following-sibling::*').remove
      n = n.parent
    end
    
    puts div
    #=> <div id="b">
    #=>     <h2>Another Section</h2>
    #=>     <section><p class="backtotop">Back to Top</p>
    #=>       
    #=>      </section>
    #=>   </div>
    

    如果您的HTML比上述更复杂,请提供实际样本以及您想要的结果。 对于您提出的任何未来问题,这是一个很好的建议。

答案 1 :(得分:0)

似乎我应该选择我需要的东西;不删除东西 - 请参阅此处的优秀解决方案 Nokogiri: Select content between element A and B