2017-03-29 2 views
1

Disons que j'ai ce html qui a différentes profondeurs de descendants et un mélange de types d'éléments:Nokogiri: appliquer la classe à l'élément qui a un certain descendant

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

Et je veux appliquer une classe de bex à tous les foos qui contiennent des classes de bar il ressemble à:

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

Comment wld-je faire avec Ruby/nokogiri? J'ai essayé toutes sortes de choses et je n'arrive pas à l'obtenir. Merci.

Édition: fermé le duh, oups.

Répondre

1

J'ai passé beaucoup de temps à me demander pourquoi le deuxième foo n'a pas été trouvé. Vos données sont brisées, "duh n'est pas fermé.

Pour sélectionner les nœuds, vous pouvez utiliser:

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

À titre d'exemple:

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 
+0

Merci qui a travaillé! Désolé de ne pas fermer le duh, duh. Si quelqu'un a envie d'expliquer comment ce cld se fait via le ciblage css plutôt qu'avec xpath, je serais intéressé à savoir. – j1mmy