2017-03-30 1 views
-1

Utilisation de ruby ​​/ nokogiri Je voudrais envelopper certains éléments en commençant par un élément et en terminant avant le prochain de ces éléments. Disons donc que j'ai:Enveloppement d'une série d'éléments frères

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

Et je veux envelopper tous foos et leurs barres contiguës (s'il y en a) dans une classe de baz qui ferme avant la prochaine foo (dernier obvs ne possède pas une autre foo), comme ceci:

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

Merci.

Edit: Je trouve ce qui pose une question similaire, mais je me bats pour l'adapter XPath axis, get all following nodes until

Edit 2: Cela renverra les barres après la foo, mais pas le foo:

body.xpath("(//div[@class='foo'])[1]/following-sibling::div[@class='bar'] 
    [1 = count(preceding-sibling::div[@class='foo'][1] | (//div[@class='foo'])[1])]") 

Besoin de comprendre comment inclure le foo!

Edit 3: Welp cela va ajouter le foo:

body.xpath("//div[@class='foo'][1]","//div[@class='foo'] 
    [1]/following-sibling::div[@class='bar'] 
    [1 = count(preceding-sibling::div[@class='foo'][1] | (//div[@class='foo'])[1])]") 

Mais le plus gros problème est que je ne suis pas sûr de savoir comment itérer cela? Il retourne juste le premier ensemble de foo + bars.

Edit 4: à travers les morceaux Itération foo-bar:

var = 1 
loop do 
    chunk = body.xpath("//div[@class='foo'][#{var}]","//div[@class='foo'] 
    [#{var}]/following-sibling::div[@class='bar'] 
    [1 = count(preceding-sibling::div[@class='foo'][#{var}] | 
    (//div[@class='foo'])[1])]") 
    puts chunk 
    var += 1 
    break if chunk.length == 0 
end 

Je ne sais pas comment les envelopper dans divs maintenant.

Répondre

0

Welp J'ai une solution inélégante probablement pour les adeptes de cette question follement populaire:

var = 1 
loop do 
    chunk = body.xpath("//div[@class='foo'][#{var}]","//div[@class='foo'] 
    [#{var}]/following-sibling::div[@class='bar'] 
    [1 = count(preceding-sibling::div[@class='foo'][#{var}] | 
    (//div[@class='foo'])[1])]") 
    break if chunk.length == 0  
    var += 1 
    puts <div class="baz"> 
    puts chunk 
    puts </div> 
end