I. XSLT 1.0 / XPath 1.0
純粋なXPath1.0でこれを行う方法はないと思います(特定の順序ではないと思います[とにかく、そこに依存するのは好きではありません)。ある種の秩序である])。
そうは言っても、キーベースのXSLT1.0ソリューションを使用して問題を解決できます。
このXSLT1.0ドキュメントの場合:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="no" indent="yes" method="text"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kFilmChildren" match="film/*" use="name()"/>
<xsl:template match="/">
<xsl:value-of
select="count(//film/*[
generate-id() =
generate-id(key('kFilmChildren', name())[1])
])"/>
</xsl:template>
</xsl:stylesheet>
...サンプルXML(ルート要素にラップされている)に対して適用されます:
<films>
<film>
<title/>
<year/>
<actor/>
</film>
<film>
<title/>
<year/>
<actor/>
</film>
</films>
...必要な結果が生成されます:
3
わずかに変更されたXMLに対して同じスタイルシートを適用する場合:
<films>
<film>
<title/>
<year/>
<actor/>
<test/>
</film>
<film>
<title/>
<year/>
<actor/>
<test/>
<test2/>
</film>
</films>
...繰り返しますが、正しい答えが生成されます:
5
注:完全なドキュメントを表示しなかったため、//
式を使用して、不足している知識を補いました。ただし、これは非常に大きな木の根元近くでの費用のかかる操作になる可能性があります。あなたはあなたをより具体的にするためにうまくいくでしょう。
II。XSLT 2.0 / XPath 2.0
distinct-values
Pure XPath 2.0を使用すると、次の式を使用して正しい答えを得ることができます。
count(distinct-values(//film/*/name()))
XSLT検証:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output omit-xml-declaration="no" indent="yes" method="text" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:value-of select="count(distinct-values(//film/*/name()))" />
</xsl:template>
</xsl:stylesheet>
結果:
3