【问题标题】:XPath / XQuery: find text in a node, but ignoring content of specific descendant elementsXPath / XQuery:在节点中查找文本,但忽略特定后代元素的内容
【发布时间】: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 文档中也可以选择所需的文本节点。 :)

标签: xpath xquery


【解决方案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 脚本中有效!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-21
      • 2021-07-16
      • 2011-07-06
      • 1970-01-01
      相关资源
      最近更新 更多