Linux|系统管理|WEB开发

关注Linux,系统管理,WEB开发以及开源世界

在xslt中不重复计算某元素的简单方法

| Comments

问题来自我的blog上的littlemouse的留言:

你好,我是个xslt新手,我能问你个问题吗?如何处理重复计数问题?比如我要计算不同人的个数,但是有的人名字重复了很多次,但是是同一个人,这样的问题如何解决呢? 非常感谢!

我们举个例子来说明:

假定xml文件如下:

1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8" ?><br />
   <?xml-stylesheet type="text/xsl" href="./test.xslt" ?><br />
   <SCENE>
 <SPEAKER>one</SPEAKER>
 <SPEAKER>two</SPEAKER>
 <SPEAKER>one</SPEAKER>
   </SCENE>

我需要计算这个xml文档里有多少个SPEAKER,当然不带重复的,上面的例子中,我们得到的结果应该是2,而不是应该是3.

下面是计算结果的xslt片断

1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8" ?><br />
   <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="SCENE">
   <xsl:value-of select="count(//SPEAKER[not(.=preceding::SPEAKER)])" />
   </xsl:template>
   </xsl:stylesheet>

上面的核心就是一句话

   count(//SPEAKER[not(.=preceding::SPEAKER)])

稍微解释一下//SPEAKER 表示搜索根节点下所有的SPEAKER子节点,然后使用带有方框的谓词not(.=preceding::SPEARK)来表示目前找到的子节点不应该和之前找到的子节点相同,符号.表示当前节点。
preceding::SPEAKER表示之前的所有SPEAKER子节点,这是典型的xpath语法。=是逻辑表示,表示相同,然后使用not谓词否定。

这样,我们就得到了所有SPEAKER子节点的列表,且不重复,最后使用count函数来计算这个列表的个数,得到最后我们需要的结果。

xslt其实是很强大的,可惜我很久没有用过它了,不过程序开发,特别是不做数据的管理,很难用到它。

Comments