我必须编写一个XSLT文档,该文档可以与任何XML文档一起使用,并在HTML表格中显示结果。表的列都取决于XML文档中有多少个标记。我试图使用
<xsl:value-of select="count(/*/*/)"/>
计算标签数量。
但我希望如果我有:
<film>
<title></title>
<year></year>
<actor></actor>
</film>
<film>
<title></title>
<year></year>
<actor></actor>
</film>
结果将是3,而不是当前显示的6。请问这个问题的任何解决方案吗?
答案 0 :(得分:1)
<强>予。假设强>:
。 。 。
<films>
<film>
<title/>
<year/>
<actor/>
</film>
<film>
<title/>
<year/>
<actor/>
</film>
</films>
和强>:
0.2。 film
个元素都具有相同数量的同名列,您只需要:
count(/*/*[1]/*)
这会生成XML文档顶部元素的第一个子元素的子元素数:
3
<强> II。另一种可能性:不同的film
元素具有不同数量的子元素,其中一个元素具有确定表格的总列数的所有子元素。
<films>
<film>
<title/>
<year/>
<actor/>
</film>
<film>
<title/>
<year/>
<actor/>
<rating/>
<director/>
</film>
<film>
<title/>
<year/>
<actor/>
<rating/>
</film>
</films>
然后,使用XPath 2.0,使用:
max(/*/*/count(*))
这将生成XML文档的top元素的子元素所具有的子元素的最大数量:
5
<强> III。最后,如果film
元素中没有一个元素包含列的所有元素,那么使用(ABach已经提出的内容):
count(distinct-values(/*/*/*/name()))
答案 1 :(得分:0)
<强>予。 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
注意:如果您没有显示完整的文档,我使用//
表达式弥补了缺乏知识的情况。然而,这可能是在非常大的树根附近进行的昂贵操作;你会做得更好,使你的更具体。
<强> II。 XSLT 2.0 / XPath 2.0
通过使用distinct-values
表达式,可以使用纯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
答案 2 :(得分:0)
您的文档实际上包含16个标记:8个开始标记和8个结束标记。所以我怀疑“计算标签”不是你真正的要求。由于您的术语不正确,我们只能猜测您的真实要求。我怀疑它可能是为每个不同的元素名称创建一个表,包含具有该名称的元素数量的计数。这将是:
<table>
<xsl:for-each-group select="//*" group-by="name()">
<tr>
<td><xsl:value-of select="current-grouping-key()"/></td>
<td><xsl:value-of select="count(current-group()"/></td>
</tr>
</xsl:for-each-group>
</table>