【问题标题】:How to remove a node using Nokogiri如何使用 Nokogiri 删除节点
【发布时间】:2017-05-27 11:11:57
【问题描述】:

我有一个这样的 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."

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

什么是这样做的好方法?

【问题讨论】:

  • 请阅读“How to Ask”,包括链接页面,以及“minimal reproducible example”。我们需要查看您编写的演示问题的最少代码。没有它,您似乎还没有尝试过。如果您熟悉 NodeSet,那么您应该在 NodeSet 文档中看到过unlink AKA remove

标签: html ruby xml xpath nokogiri


【解决方案1】:

第一个问题

删除所有脚本节点:

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"

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

第二个问题

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

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


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

【讨论】:

【解决方案2】:

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>

此时&lt;div&gt;中的文字是:

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

【讨论】:

    猜你喜欢
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多