ruby - XPath 轴,获取所有后续节点直到

标签 ruby xpath nokogiri

我有以下 HTML 示例:

<!-- lots of html -->
<h2>Foo bar</h2>
<p>lorem</p>
<p>ipsum</p>
<p>etc</p>

<h2>Bar baz</h2>
<p>dum dum dum</p>
<p>poopfiddles</p>
<!-- lots more html ... -->

我希望提取“Foo bar”标题后的所有段落,直到到达“Bar baz”标题(“Bar baz”标题的文本未知,所以很遗憾我无法使用答案由 bougyman 提供)。现在我当然可以使用 //h2[text()='Foo bar']/following::p 之类的东西,但这当然会抓取此后的所有段落 header 。因此,我可以选择遍历节点集并将段落插入数组,直到文本与下一个 header 的文本相匹配,但老实说,这远不如在 XPath 中完成这件事那么酷。

有没有办法做到这一点我想念的?

最佳答案

使用:

(//h2[. = 'Foo bar'])[1]/following-sibling::p
   [1 = count(preceding-sibling::h2[1] | (//h2[. = 'Foo bar'])[1])]

如果保证每个 h2 都有不同的值,这可以简化为:

//h2[. = 'Foo bar']/following-sibling::p
   [1 = count(preceding-sibling::h2[1] | ../h2[. = 'Foo bar'])]

这意味着:选择 h2(文档中的第一个或唯一一个)的兄弟元素之后的所有 p 元素,其字符串值为是 'Foo bar' 并且所有这些 p 元素的第一个前面的兄弟 h2 正是 h2(第一个或唯一一个在文档中)其字符串值为'Foo bar'`。

这里我们使用一种判断两个节点是否相同的方法:

count($n1 | $n2) = 1

当节点 $n1$n2 是同一节点时,为 true()

这个表达式可以泛化:

$x/following-sibling::p
       [1 = count(preceding-sibling::node()[name() = name($x)][1] | $x)]

选择 $x 指定的任何节点的所有“紧随其后的兄弟节点”

关于ruby - XPath 轴,获取所有后续节点直到,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4767430/

相关文章:

ruby - 如何删除具有给定 src 属性的图像节点?

ruby - 将 HTML 转换为纯文本(包含 <br>s)

ruby - 在 Google Drive API 中收到错误 403 - 超出了未经身份验证使用的每日限制。继续使用需要注册

ruby-on-rails - ExecJS::RuntimeError: SyntaxError: 意外的标记:运算符 (>) (行:22342,列:24,位置:826182)

ruby - 如何从日数和年份获取日期?

c# - 异常 : The XPath expression evaluated to unexpected type System. Xml.Linq.XAttribute

ruby - 如何在 XPath 中获取序列的最后一个元素?

mysql - 通过 ruby​​ Rails 迁移添加 MySQL 枚举列时出现问题

java - 如何使用 AND 运算符编写 XPath 以在单个 XPath 中添加多个跨度?

XSLT 1.0 : how to go for the "parent" axis