【问题标题】:Xpath expression to find non-child elements by attributeXpath 表达式按属性查找非子元素
【发布时间】:2012-07-07 08:23:03
【问题描述】:

这是一个很好的谜题。假设我们有这段代码:

<page n="1">
 <line n="3">...</line>
</page>

page 元素 "n=1" 中定位 line 元素 "n=3" 真的很容易,只需一个简单的 xpath 表达式:xpath(//页[@n='1')/行[@n='3'])。伟大的,美丽的,优雅的。 现在假设我们拥有的是这种编码(熟悉 TEI 的人会知道它来自哪里)。

<pb n="1"/>
(arbitrary amounts of stuff)
<lb n="3"/>

我们想找到 n="3" 的 lb 元素,它跟在 n="1" 的 pb 元素之后。但请注意——这个 lb 元素几乎可以在 pb 之后的任何位置:它可能不是(并且很可能不是)兄弟,但可能是 a 的子元素pb 的兄弟姐妹,或 pb 的父级的兄弟,等等等等。

所以我的问题是:你将如何使用 XPath 搜索这个带有 n="3" 的 lb 元素,它紧跟在带有 n="1" 的 pb 元素之后?

提前致谢

彼得

【问题讨论】:

    标签: xpath attributes


    【解决方案1】:

    使用

      //pb[@n='1']/following::lb[@n='2']
    |
      //pb[@n='1']/descendant::lb[@n='2']
    

    这会选择按文档顺序跟随指定pb 的任何lb 元素——即使所需的lb 元素是pb 元素的后代。

    请注意 以下表达式通常不会选择所有想要的 lb 元素(它无法选择其中任何一个pb 元素的后代):

      //pb[@n='1']/following::lb[@n='2']
    

    解释

    根据 W3C XPath specification 中的定义,following::descendant:: 轴不重叠:

    "以下轴包含与该轴相同的文档中的所有节点 在文档顺序中位于上下文节点之后的上下文节点, 排除任何后代并排除属性节点和命名空间节点"

    【讨论】:

      【解决方案2】:

      那就是

      //pb[@n=1]/following::lb[@n=3]
      

      【讨论】:

      • 请注意,following 轴选择上下文节点的 关闭 标记之后的所有内容,因此如果它是 后代,则它不会匹配 lb pb 的节点。但是,根据您的规范,这不是必需的。
      • Brilliant!so 在 之后的 之后的 -- 即第 2 行第 1r 页中的 a 列,这应该是: //pb[@n=1r]/following::cb[@n=a]/following::lb[@n=2] ...yes?
      • 是的,但是如果您的属性值是字符串而不是数字,您确实必须使用引号://pb[@n='1r']/following::cb[@n='a']/following::lb[@n='2']
      • 谢谢!你解决了一个很好的问题。 (问题——是否所有的 xpath 系统都支持以下::? 之前没有见过
      • 是的,following 轴是在 XPath 1.0 中定义的:w3.org/TR/xpath/#axes
      猜你喜欢
      • 2019-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-05
      • 2012-05-13
      • 1970-01-01
      • 2019-05-29
      • 1970-01-01
      相关资源
      最近更新 更多