子孫と子孫のテキスト()を備えたXpathクエリ()述語
-
29-09-2019 - |
質問
「div」または「テーブル」要素を返すxpathクエリを作成したいと思います。「ABC」というテキストを含む子孫がある限り。 1つの注意点は、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::*
トラバーサルはaに比べて非常に安価です 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>
ノート: :DOMなどのXSLT(XPath 1.0ホスト)を使用する必要はありません。同じ結果を取得する必要があります。
他のヒント
//*[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