如何让所有元素跟随一次,例如:
<div id="exemple">
<h2 class="target">foo</h2>
<p>bla bla</p>
<ul>
<li>bar1</li>
<li>bar2</li>
<li>bar3</li>
</ul>
<h4>baz</h4>
<ul>
<li>lot</li>
</ul>
<div>of</div>
<p>possible</p>
<p>tags</p>
<a href="#">after</a>
</div>
我需要检测<h2 class="target">
并将所有标记转到下一个<h4>
并忽略<h4>
AND 所有关注标记(如果<h4>
没有存在,我必须将所有标签都放到父[[此处:<div>
的结尾])
内容是动态且不可预测的唯一的规则是:我们知道有一个目标,并且有一个(或元素的结尾)。我需要在两者之间获取所有标签并排除所有其他标签。
有了这个例子,我需要获得以下HTML:
<h2 class="target">foo</h2>
<p>bla bla</p>
<ul>
<li>bar1</li>
<li>bar2</li>
<li>bar3</li>
</ul>
所以我可以得到:target = page.at('#exemple .target')
我知道next_sibling
方法,但是如何测试当前节点的标签类型?
我认为这样的事情就是节点树:
html = ''
while not target.is_a? 'h4'
html << target.inner_html
target = target.next_sibling
我该怎么做?
答案 0 :(得分:2)
您可以从节点集中减去不需要的那些:
h2 = page.at('h2')
(h2.search('~ *') - h2.search('~ h4','~ h4 ~ *')).each do |el|
# el is not a h4 and does not follow a h4
end
使用xpath可能更有意义,但我可以在没有谷歌搜索的情况下这样做。
您对迭代下一个兄弟的想法也可以起作用:
el = page.at('h2 ~ *')
while el && el.name != 'h4'
# do something with el
el = el.at('+ *')
end
答案 1 :(得分:1)
看起来您想要返回h2
元素及其后续兄弟元素。我不清楚你是想保留还是丢弃h4
;如果你想保留XPath将是:
//h2[@class="target"] | //h2[@class="target"]/following-sibling::*
如果您需要排除h4
:
//h2[@class="target"] | //h2[@class="target"]/following-sibling::*[not(self::h4)]
修改:如果您需要排除h4
以及其他内容:
//h2[@class="target"] | //h2[@class="target"]/following-sibling::*[not(self::h4) | not(preceding-sibling::h4)]