我有一个HTML文档作为字符串。我用Nokogiri解析了它:
doc_str = <<-mydoc
<p>Lorem ipsum dolor sit foo.</p>
<h2>Consectetur adipisicing bar</h2>
<p>Foo do <a href="/c-foo.aspx" class = "foo" title="Foo bar.">foofoo foo</a>.</p>
mydoc
doc = Nokogiri::HTML doc_str
我希望在所有可见文字中将"foo"
/ "Foo"
替换为"Bar"
/ "bar"
:
desired = <<-mydoc
<p>Lorem ipsum dolor sit bar.</p>
<h2>Consectetur adipisicing bar</h2>
<p>Bar do <a href="/c-foo.aspx" class = "foo" title="Bar bar.">foofoo bar</a>.</p>
mydoc
我该怎么做?
我尝试阅读Nokogiri tutorial,其中描述了Nokogiri::HTML::Document#at_css
。使用Ruby 2.0和最新的Nokogiri,doc.at_css 'h1'
返回nil
,因此h1.content = "something"
甚至不可能。
即使它有效,它也只是解决我的发现和替换问题的第一步。
答案 0 :(得分:3)
doc.at_css 'h1'
会返回nil
,因为HTML中没有h1
个元素。 doc.at_css 'h2'
正确返回Nokogiri::XML::Element
元素的h2
对象。
CSS选择器无法选择文本节点,并且对于这类事物来说是一个糟糕的工具。 XPath将完成CSS所做的一切以及更多。文档根目录下任何位置的文本节点都只是//text()
。
编辑我刚刚注意到您似乎希望属性的内容以相同的方式发生变化。 @*
匹配任何属性,因此XPath表达式变为//@* | //text()
。虽然我不清楚这一点,因为href="/c-foo.aspx"
和class="foo"
保持不变,但title="Foo bar."
变为title="bar bar."
。我相信你可以自己解决这个问题。
您需要使用XPath查找所有文本节点,然后使用content
获取每个节点的文本值。根据需要进行修改,并使用content=
替换它。
该程序演示。 to_html
方法将数据包装在使其成为有效HTML所必需的标记中。
require 'nokogiri'
doc_str = <<-HTML
<p>Lorem ipsum dolor sit foo.</p>
<h2>Consectetur adipisicing bar</h2>
<p>Foo do <a href="/c-foo.aspx" class = "foo" title="Foo bar.">foofoo foo</a>.</p>
HTML
doc = Nokogiri::HTML(doc_str)
doc.xpath('//@*', '//text()').each do |node|
node.content = node.content.gsub(/\bfoo\b/, 'bar').gsub(/\bFoo\b/, 'Bar')
end
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>
<p>Lorem ipsum dolor sit bar.</p>
<h2>Consectetur adipisicing bar</h2>
<p>Bar do <a href="/c-bar.aspx" class="bar" title="Bar bar.">foofoo bar</a>.</p>
</body></html>