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:在节点中查找文本,但忽略特定后代元素的内容的主要内容,如果未能解决你的问题,请参考以下文章