带有后代和后代 text() 谓词的 XPath 查询 [英] XPath query with descendant and descendant text() predicates
问题描述
我想构造一个 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"
的任何文本节点,选择其第一个祖先,即 div
或 table
.
这样效率更高,因为只需要对文档树(而不是其他任何)进行一次完整扫描,并且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屋!