使用:
($yourNode/preceding::Q | $yourNode/ancestor::Q)/@id
XSLT ベースの検証:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vQg" select="(//Q[@id='g'])[1]"/>
<xsl:variable name="vQf" select="(//Q[@id='f'])[1]"/>
<xsl:template match="/">
"Preceding" $vQg:
<xsl:for-each select=
"($vQg/preceding::Q | $vQg/ancestor::Q)/@id">
<xsl:value-of select="concat(., ' ')"/>
</xsl:for-each>
=====================
"Preceding" $vQf:
<xsl:for-each select=
"($vQf/preceding::Q | $vQf/ancestor::Q)/@id">
<xsl:value-of select="concat(., ' ')"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
この変換が提供された XML ドキュメントに適用されると、次のようになります。
<root>
<Q id="a">1</Q>
<Q id="b">2</Q>
<Q id="c">3</Q>
<x>
<Q id="d">3.1</Q>
<Q id="e">3.2</Q>
<Q id="f">3.3</Q>
</x>
<Q id="g">4</Q>
<Q id="h">5</Q>
</root>
XPath 式は (Q
質問の 2 つの要素に対して) 2 回評価され、結果の文字列値はスペースで区切られて出力されます。
"Preceding" $vQg:
a b c d e f
=====================
"Preceding" $vQf:
a b c d e
説明:
preceding::
軸は、ドキュメントの順序で先行するすべてのノードを選択するわけではありません。これを行うには、軸も使用する必要がありますancestor::
。
W3C XPath 1.0 仕様から:
"•前の軸には、ドキュメントの順序でコンテキスト ノードの前にあるコンテキスト ノードと同じドキュメント内のすべてのノードが含まれます。祖先はすべて除外され、属性ノードと名前空間ノードは除外されます"