X Path先后查询后代和后代文本()谓词
-
29-09-2019 - |
题
我想构建一个XPath查询,该查询将返回“ DIV”或“表”元素,只要它具有包含文本“ ABC”的后代。一个警告是它不能有任何Div或桌子后代。
<div>
<table>
<form>
<div>
<span>
<p>abcdefg</p>
</span>
</div>
<table>
<span>
<p>123456</p>
</span>
</table>
</form>
</table>
</div>
因此,此查询的唯一正确结果是:
/div/table/form/div
我最好的尝试看起来像这样:
//div[contains(//text(), "abc") and not(descendant::div or descendant::table)] | //table[contains(//text(), "abc") and not(descendant::div or descendant::table)]
但不返回正确的结果。
谢谢你的帮助。
解决方案
有些不同: :)
//text()[contains(.,'abc')]/ancestor::*[self::div or self::table][1]
似乎比其他解决方案短得多,不是吗? :)
翻译成简单的英语: :对于文档中包含字符串的任何文本节点 "abc"
选择其第一个祖先 div
或a table
.
这更有效, ,因为只需要对文档树的全面扫描(而不是其他),并且 ancestor::*
与一个相比,遍历非常便宜 descendent::
(树)扫描。
验证该解决方案“确实有效”:
<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>
当在提供的XML文档上执行此转换时:
<div>
<table>
<form>
<div>
<span>
<p>abcdefg</p>
</span>
</div>
<table>
<span>
<p>123456</p>
</span>
</table>
</form>
</table>
</div>
想要的,正确的结果被产生:
<div>
<span>
<p>abcdefg</p>
</span>
</div>
笔记: :不必使用XSLT - 任何XPATH 1.0主机 - 例如DOM,必须获得相同的结果。
其他提示
//*[self::div|self::table]
[descendant::text()[contains(.,"abc")]]
[not(descendant::div|descendant::table)]
问题 contains(//text(), "abc")
是施放第一个节点的函数铸造节点集。
您可以尝试:
//div[
descendant::text()[contains(., "abc")]
and not(descendant::div or descendant::table)
] |
//table[
descendant::text()[contains(., "abc")]
and not(descendant::div or descendant::table)
]
这有帮助吗?
不隶属于 StackOverflow