包装一系列兄弟元素

时间:2017-03-30 02:15:52

标签: ruby xpath nokogiri

使用ruby / nokogiri我想从一个元素开始并在下一个元素之前结束一些元素。所以我要说:

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

我想要在下一个foo之前关闭的baz类中包含所有foos及其连续的条(如果有的话)(最后一个obvs没有另外的foo),如下所示:

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

感谢。

编辑:我发现这个问题是一个类似的问题,但我正努力适应它XPath axis, get all following nodes until

编辑2:这将返回foo之后的条形而不是foo:

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

需要弄清楚如何包含foo!

编辑3:Welp这将添加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])]")

但更大的问题是我不确定如何迭代这个?它只返回第一组foo + bars。

编辑4:迭代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

现在不确定如何将它们包装在div中。

1 个答案:

答案 0 :(得分:0)

Welp我对这个非常受欢迎的问题的粉丝有一个可能不太优雅的解决方案:

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