如何使用Nokogiri删除节点

时间:2017-01-12 11:06:39

标签: html ruby xml xpath nokogiri

我有这样的HTML结构:

<div>
  This is
  <p> very
    <script>
      some code
    </script>
  </p>
   important.
</div>

我知道如何从中获取Nokogiri::XML::NodeSet

dom.xpath("//div")

我现在想要过滤掉任何script标记:

dom.xpath("//script")

所以我可以得到类似的东西:

<div>
  This is
  <p> very</p>
   important.
</div>

这样我就可以致电div.text来获取:

"This is very important."

我尝试递归/迭代地遍历所有子节点并尝试匹配我想要过滤掉我不想要的任何节点的每个节点,但是我遇到了像太多空格或没有足够空格的问题。我非常确定这是一个非常好的和rubyesque方式。

这样做的好方法是什么?

2 个答案:

答案 0 :(得分:0)

第一个问题

删除所有脚本节点:

init()

感谢@theTinMan的提示(在一个NodeSet上调用require 'nokogiri' html = "<div> This is <p> very <script> some code </script> </p> important. </div>" doc = Nokogiri::HTML(html) doc.xpath("//script").remove p doc.text #=> "\n This is\n very\n \n \n important.\n" 而不是每个节点。)

第二个问题

要删除不需要的空格,您可以使用:

  • remove删除字符串开头和结尾的空格(空格,制表符,换行符......)
  • strip只用一个空格替换多个空格


gsub

答案 1 :(得分:0)

NodeSet包含remove方法,可以轻松删除与您的选择器匹配的内容:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<html>
  <body>
    <div><p>foo</p><p>bar</p></div>
  </body>
</html>
EOT

doc.search('p').remove
puts doc.to_html

# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# >> <html>
# >>   <body>
# >>     <div></div>
# >>   </body>
# >> </html>

应用于您的样本输入:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<div>
  This is
  <p> very
    <script>
      some code
    </script>
  </p>
  important.
</div>
EOT

doc.search('script').remove
puts doc.to_html

# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# >> <html><body>
# >> <div>
# >>   This is
# >>   <p> very
# >>     
# >>   </p>
# >>    important.
# >> </div>
# >> </body></html>

此时<div>中的文字是:

doc.at('div').text # => "\n  This is\n   very\n    \n  \n   important.\n"

规范化很容易:

doc.at('div').text.gsub(/[\n ]+/,' ').strip # => "This is very important."
相关问题