我。 XSLT 1.0/XPath 1.0
我不相信有办法使用纯 XPath 1.0 来做到这一点(因为您正在寻找不同的元素名称,我认为这些名称没有任何特定的顺序 [无论如何,我不喜欢依赖于某种顺序])。
也就是说,您可以使用基于密钥的 XSLT 1.0 解决方案来解决问题。
当这个 XSLT 1.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
注意:鉴于您没有展示完整的文档,我通过使用 // 表达式来弥补知识的不足。然而,在非常大的树根附近,这可能是一项昂贵的操作。你最好让你的更具体。
二。 XSLT 2.0/XPath 2.0
Pure XPath 2.0 可以通过使用distinct-values 表达式来获得正确答案:
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