XPath / XQuery:在节点中查找文本,但忽略特定后代元素的内容

Posted

技术标签:

【中文标题】XPath / XQuery:在节点中查找文本,但忽略特定后代元素的内容【英文标题】:XPath / XQuery: find text in a node, but ignoring content of specific descendant elements 【发布时间】:2011-06-11 18:00:18 【问题描述】:

我正在尝试找到一种在节点内搜索字符串的方法,但不包括这些节点的某些子元素的内容。简单明了,我想在文本段落中搜索字符串,不包括作为段落子元素的脚注。

例如,

我的文件是:

<document>
   <p n="1">My text starts here/</p>
   <p n="2">Then it goes on there<footnote>It's not a very long text!</footnote></p>
</document>

当我搜索“text”时,我希望Xpath / XQuery 检索第一个 p 元素,而不是第二个(其中“text”仅包含在脚注子元素中)。

我尝试了contains() 函数,但它检索了两个p 元素。

任何帮助将不胜感激:)

【问题讨论】:

好问题,+1。请参阅我的答案,以获得一个简短的 XPath 1.0 表达式,即使在更复杂的 XML 文档中也可以选择所需的文本节点。 :) 【参考方案1】:

我想搜索一个字符串 文本的段落,不包括 作为子元素的脚注 的段落

XPath 1.0 - 唯一的解决方案:

使用

//p//text()[not(ancestor::footnote) and contains(.,'text')]

针对以下 XML 文档(从您的文档中获得,但在 footnote 中添加了 p 以使其更有趣):

<document>
    <p n="1">My text starts here/</p>
    <p n="2">Then it goes on there
        <footnote>It's not a very long text!
           <p>text</p>
        </footnote>
    </p>
</document>

这个 XPath 表达式准确地选择了想要的文本节点

My text starts here/

【讨论】:

【参考方案2】:
//p[(.//text() except .//footnote//text())[contains(., 'text')]]

【讨论】:

【参考方案3】:

/document/p[text()[contains(., 'text')]] 应该可以。

【讨论】:

谢谢马丁!唯一的问题是在 p 中选择“文本”,忽略 all 子元素的内容。我只想忽略脚注元素。 您能否用一些更具代表性的 XML 示例更新您的问题,以便更清楚地了解需求是什么? /document/p[descendant-or-self::*[not(self::footnote)]/text()[contains(., 'text')]] 够用吗?【参考方案4】:

作为记录,作为对其他答案的补充,我发现这种解决方法似乎也可以完成这项工作:

//p[contains(child::text()|not(descendant::footnote), "text")]

【讨论】:

这不是一个有效的 XPath 表达式。联合运算符 (|) 要求其两个操作数都是节点,但 not() 函数的返回类型是 xs:boolean -- 任何兼容的 XPath 引擎必须 引发错误。 哎呀,你说得对,Dimitre,Oxygen 引发了错误。奇怪,这个表达式在我的 php 脚本中有效!

以上是关于XPath / XQuery:在节点中查找文本,但忽略特定后代元素的内容的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 XQuery 检索父节点?

XPath注入

Python爬虫之xlml解析库

XQuery/XPath:元素 id 在输出中丢失

(转)Xpath语法格式整理

DOM xpath 查找#text 节点并包含在段落标记中