以下は、同じドキュメント内の任意のノード セットに属する任意のノードで機能する一般的なソリューションです。
XSLT を使用してソリューションを実装していますが、最終的に他のホスティング言語で使用できる単一の XPath 式を取得します。
をノード$vNodeSet
セットと$vNode
し、位置を見つけたいこのノードセット内のノードとします。
次に、 let$vPrecNodes
には、 の前にある XML ドキュメント内のすべてのノードが含まれます$vNode
。
次に、 let$vAncNodes
には、 の祖先である XML ドキュメント内のすべてのノードが含まれます$vNode
。
ドキュメント順$vNodeSet
で前にある のノードのセットは、 にも属するノードセット内のすべてのノードと、 にも属するノードセット内のすべてのノードで構成されます。$vNode
$vPrecNodes
$vAncNodes
2 つのノードセットの交差には、よく知られているケイシアンの公式を使用します。
$ns1[count(.|$ns2) = count($ns2)]
$ns1
との交点にあるノードを正確に含みます$ns2
。
これらすべてに基づいて、ドキュメントの順序で先行する$vPrecInNodeSet
ノードのセットをみましょう。次の XPath 式は を定義します。$vNodeSet
$vNode
$vPrecInNodeSet
$vNodeSet
[count(.|$vPrecNodes) = count($vPrecNodes)
or
count(.|$vAncNodes) = count($vAncNodes)
]
最後に、必要な位置は次のとおりです。count($vPrecInNodeSet) +1
これがすべて一緒に機能する方法は次のとおりです。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="vNodeSet" select="/*/a/b"/>
<xsl:variable name="vNode" select="$vNodeSet[. = 'tsr'][1]"/>
<xsl:variable name="vPrecNodes" select="$vNode/preceding::node()"/>
<xsl:variable name="vAncNodes" select="$vNode/ancestor::node()"/>
<xsl:variable name="vPrecInNodeSet" select=
"$vNodeSet
[count(.|$vPrecNodes) = count($vPrecNodes)
or
count(.|$vAncNodes) = count($vAncNodes)
]
"/>
<xsl:template match="/">
<xsl:value-of select="count($vPrecInNodeSet) +1"/>
</xsl:template>
</xsl:stylesheet>
提供された XML ドキュメントに上記の変換を適用すると、次のようになります。
<root>
<a>
<b>zyx</b>
</a>
<a>
<b>wvu</b>
</a>
<a>
<b>tsr</b>
</a>
<a>
<b>qpo</b>
</a>
</root>
正しい結果が生成されます。
3
注: このソリューションは XSLT に依存しません (説明目的でのみ使用されます)。置換する変数がなくなるまで、変数をその定義に置き換えて、1 つの XPath 式を組み立てることができます。