我有这样的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方式。
这样做的好方法是什么?
答案 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."