带有后代和后代 text() 谓词的 XPath 查询 [英] XPath query with descendant and descendant text() predicates

查看:26
本文介绍了带有后代和后代 text() 谓词的 XPath 查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想构造一个 XPath 查询,该查询将返回一个div"或table"元素,只要它有一个包含文本abc"的后代.一个警告是它不能有任何 div 或 table 后代.

<表格><表格><div><跨度><p>abcdefg</p></span>

<表格><跨度><p>123456</p></span></表单>

所以这个查询的唯一正确结果是:

/div/table/form/div

我最好的尝试是这样的:

//div[contains(//text(), "abc") 和 not(descendant::div 或descendant::table)] |//table[contains(//text(), "abc") and not(descendant::div orDescendant::table)]

但没有返回正确的结果.

感谢您的帮助.

解决方案

有所不同: :)

//text()[contains(.,'abc')]/ancestor::*[self::div or self::table][1]

似乎比其他解决方案短很多,不是吗?:)

翻译为简单英语:对于文档中包含字符串 "abc" 的任何文本节点,选择其第一个祖先,即 divtable.

这样效率更高,因为只需要对文档树(而不是其他任何)进行一次完整扫描,并且ancestor::* 遍历非常便宜与 descendent::(树)扫描相比.

要验证此解决方案确实有效":

<xsl:output omit-xml-declaration="yes" indent="yes"/><xsl:strip-space elements="*"/><xsl:template match="/"><xsl:copy-of select="//text()[contains(.,'abc')]/ancestor::*[self::div or self::table][1] "/></xsl:模板></xsl:stylesheet>

对提供的 XML 文档执行此转换时:

<表格><表格><div><跨度><p>abcdefg</p></span>

<表格><跨度><p>123456</p></span></表单>

产生想要的、正确的结果:

<跨度><p>abcdefg</p></span>

注意:没有必要使用 XSLT——任何 XPath 1.0 主机——例如 DOM,都必须获得相同的结果.

I would like to construct an XPath query that will return a "div" or "table" element, so long as it has a descendant containing the text "abc". The one caveat is that it can not have any div or table descendants.

<div>
  <table>
    <form>
      <div>
        <span>
          <p>abcdefg</p>
        </span>
      </div>
      <table>
        <span>
          <p>123456</p>
        </span>
      </table>
    </form>
  </table>
</div>

So the only correct result of this query would be:

/div/table/form/div 

My best attempt looks something like this:

//div[contains(//text(), "abc") and not(descendant::div or descendant::table)] | //table[contains(//text(), "abc") and not(descendant::div or descendant::table)]

but does not return the correct result.

Thanks for your help.

解决方案

Something different: :)

//text()[contains(.,'abc')]/ancestor::*[self::div or self::table][1]

Seems a lot shorter than the other solutions, doesn't it? :)

Translated to simple English: For any text node in the document that contains the string "abc" select its first ancestor that is either a div or a table.

This is more efficient, as only one full scan of the document tree (and not any other) is required, and the ancestor::* traversal is very cheap compared to a descendent:: (tree) scan.

To verify that this solution "really works":

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
  <xsl:copy-of select=
  "//text()[contains(.,'abc')]/ancestor::*[self::div or self::table][1] "/>
 </xsl:template>
</xsl:stylesheet>

when this transformation is performed on the provided XML document:

<div>
  <table>
    <form>
      <div>
        <span>
          <p>abcdefg</p>
        </span>
      </div>
      <table>
        <span>
          <p>123456</p>
        </span>
      </table>
    </form>
  </table>
</div>

the wanted, correct result is produced:

<div>
   <span>
      <p>abcdefg</p>
   </span>
</div>

Note: It isn't necessary to use XSLT -- any XPath 1.0 host -- such as DOM, must obtain the same result.

这篇关于带有后代和后代 text() 谓词的 XPath 查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆