如何使用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."

我尝试递归/迭代地遍历所有子节点,并尝试匹配每个节点,我想过滤掉我不想要的任何节点,但我遇到了空格过多或空格不足等问题。我很确定有一种足够好和红宝石的方式。

这样做的好方法是什么?

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 isn   veryn    n  n   important.n"

规范化这很容易:

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

第一个问题

要删除所有脚本节点:

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 isn   veryn    n  n   important.n"

感谢@theTinMan的提示(在一个节点集而不是每个节点上调用remove)。

第二个问题

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

  • strip删除字符串开头和结尾的空格(空格、制表符、换行符等)
  • gsub仅用一个空格替换多个空格


p doc.text.strip.gsub(/[[:space:]]+/,' ')
#=> "This is very important."

相关内容

  • 没有找到相关文章

最新更新