假设有以下标记:
<p>
<code>foo</code><code>bar</code>
<code>jim</code> and then <code>jam</code>
</p>
我需要选择前三个
<code>
元素,但不包括最后一个。逻辑是“选择所有具有前面或后面的兄弟元素element,这些兄弟元素也是code
元素,除非它们之间存在一个或多个具有非空格内容的文本节点。”考虑到我正在使用Nokogiri(使用libxml2),因此只能使用XPath 1.0表达式。
虽然期望使用巧妙的XPath表达式,但在Nokogiri文档上执行相同操作的Ruby代码/迭代也可以接受。
请注意,CSS 相邻兄弟选择器会忽略非元素节点,因此选择
nokodoc.css('code + code')
将错误地选择最后一个<code>
块。Nokogiri.XML('<r><a/><b/> and <c/></r>').css('* + *').map(&:name)
#=> ["b", "c"]
编辑:为了更清晰明了,增加了更多的测试用例:
<section><ul>
<li>Go to <code>N</code> and
then <code>Y</code><code>Y</code><code>Y</code>.
</li>
<li>If you see <code>N</code> or <code>N</code> then…</li>
</ul>
<p>Elsewhere there might be: <code>N</code></p>
<p><code>N</code> across parents.</p>
<p>Then: <code>Y</code> <code>Y</code><code>Y</code> and <code>N</code>.</p>
<p><code>N</code><br/><code>N</code> elements interrupt, too.</p>
</section>
所有的
Y
都应该被选中。没有N
应该被选中。 <code>
标签的内容仅用于指示哪些应该被选择:您不能使用内容来确定是否选择元素。
<code>
出现的上下文元素是无关紧要的。它们可能出现在<li>
中,也可能出现在<p>
中,或者其他地方。我想一次选择所有连续运行的
<code>
。在其中一个Y
集合的中间有一个空格字符并不是错误。
to_s
回转和重新解析只是为了使用正则表达式操纵 HTML,这会让我感到非常恶心。 ;) - Phrogz