如何更改具有匹配内容的元素类

时间:2017-03-29 05:43:42

标签: ruby nokogiri

我有:

os.write(c);

我希望包含与“bar”类相同内容的所有元素也有一个“bar”类,如下所示:

<div class="bar">baz</div>
<div class="foo">qux</div>
<div class="foo">qux</div>
<div class="foo">baz</div>
<div class="foo">qux</div>
<div class="foo">baz</div>
<div class="foo">qux</div>

但我不能只搜索“baz”,因为该内容可能会有所变化。相反,我必须弄清楚单独的“bar”div中的内容然后找到匹配它的其他内容并将其类别更改为“bar”。

我设法将第一个“bar”元素的内容变为变量:

<div class="bar">baz</div>
<div class="foo">qux</div>
<div class="foo">qux</div>
<div class="bar">baz</div>
<div class="foo">qux</div>
<div class="bar">baz</div>
<div class="foo">qux</div>

但是我没有尝试过,只要找到匹配的内容并替换课程就行了。

3 个答案:

答案 0 :(得分:0)

您可以使用body.css('div:contains("<text-to-match>")')来匹配包含所需文本内容的节点。

您可以通过以下方式实现您想要的目标:

require 'nokogiri'

input = '<div class="bar">baz</div>
<div class="foo">qux</div>
<div class="foo">qux</div>
<div class="foo">baz</div>
<div class="foo">qux</div>
<div class="foo">baz</div>
<div class="foo">qux</div>'

body = Nokogiri::HTML.fragment(input)

text_to_match = body.at_css('.bar').text

matching_nodes = body.css("div:contains('#{text_to_match}')")
matching_nodes.each do |node|
  node['class'] = 'bar'
end

puts body.to_html

答案 1 :(得分:0)

小心使用body.css("div:contains('#{text_to_match}')")

input = '<div class="bar">baz</div>
<div class="foo">qux</div>
<div class="foo">qux</div>
<div class="foo">baza</div>
<div class="foo">qux</div>
<div class="foo">bazfdsfsdf</div>
<div class="foo">qux</div>'

输出将是:

<div class="bar">baz</div>
<div class="foo">qux</div>
<div class="foo">qux</div>
<div class="bar">baza</div>
<div class="foo">qux</div>
<div class="bar">bazfdsfsdf</div>
<div class="foo">qux</div>

如果要匹配两个元素中完全相同的文本,则应使用: body.css("div[text() = '#{text_to_match}']")

input = '<div class="bar">baz</div>
<div class="foo">qux</div>
<div class="foo">qux</div>
<div class="foo">baza</div>
<div class="foo">qux</div>
<div class="foo">bazfdsfsdf</div>
<div class="foo">baz</div>'

输出结果为:

<div class="bar">baz</div>
<div class="foo">qux</div>
<div class="foo">qux</div>
<div class="foo">baza</div>
<div class="foo">qux</div>
<div class="foo">bazfdsfsdf</div>
<div class="bar">baz</div>

答案 2 :(得分:0)

我做这样的事情:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<div class="bar">baz</div>
<div class="foo">qux</div>
<div class="foo">baz</div>
EOT

target_text = doc.at('.bar').text # => "baz"
doc.search("//div[text()='#{target_text}']").each do |div|
  div['class'] = 'bar'
end

结果是:

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

没有任何迹象表明我们无法混合使用CSS和XPath选择器。 XPath有更多的功能,但它在视觉上很嘈杂,所以我在可以使用CSS和XPath时必须使用。

XPath可以轻松搜索所有节点的文本,因此它是该任务的不错选择。