Nokogiri:将 class 应用于具有特定后代的元素

Nokogiri: apply class to element that has a certain descendant

假设我有这个 html,它具有不同深度的后代和元素类型的混合:

<div class="foo">
    <div class="bar"></div>
</div>
<div class="foo">
    <div class="baz"></div>
</div>
<div class="foo">
    <u><span class="duh">
        <div class="bar"></div>
    </span></u>
</div>
<div class="foo">
    <div class="baz"></div>
</div>

我想将 class 的 bex 应用到所有包含 classes bar 的 foos,所以它看起来像:

<div class="bex">
    <div class="bar"></div>
</div>
<div class="foo">
    <div class="baz"></div>
</div>
<div class="bex">
    <u><span class="duh">
        <div class="bar"></div>
    </span></u>
</div>
<div class="foo">
    <div class="baz"></div>
</div>

我如何用 ruby/nokogiri 做到这一点?尝试了各种各样的东西,但无法完全理解。谢谢

编辑:关闭 duh,糟糕。

我花了很长时间想知道为什么没有找到第二个 foo。 您的数据已损坏,"duh 未关闭。

到select节点,可以使用:

doc.xpath("//div[@class='foo' and .//div[@class='bar']]")

举个例子:

data = %q(<div class="foo">
    <div class="bar"></div>
</div>
<div class="foo">
    <div class="baz"></div>
</div>
<div class="foo">
    <u><span class="duh">
        <div class="bar"></div>
    </span></u>
</div>
<div class="foo">
    <div class="baz"></div>
</div>)

require 'nokogiri'

doc = Nokogiri.HTML(data)

doc.xpath("//div[@class='foo' and .//div[@class='bar']]").each do |node|
  node["class"] = 'bex'
end

puts doc