2013-11-26 105 views
1

我想计数以XML相同的元件的数量, 就像uniq -c确实为文本文件如何在xslt中实现“uniq -c”?

输入:

<doc> 
    <page> 
    <elem>a</elem> 
    <elem>a</elem> 
    <elem>a</elem> 
    <elem>b</elem> 
    <elem>b</elem> 
    <elem>c</elem> 
    <elem>a</elem> 
    <elem>a</elem> 
    </page> 
</doc> 

预期输出:

<doc> 
    <page> 
    <elem c="3">a</elem> 
    <elem c="2">b</elem> 
    <elem c="1">c</elem> 
    <elem c="2">a</elem> 
    </page> 
</doc> 
+1

你的尝试是什么? – vels4j

回答

2

在XSLT 2.0使用<xsl:for-each-group select="elem" group-adjacent=".">这会很容易,但它在XSLT 1.0中相当复杂。我会用尾递归模板来模拟“而循环”来解决:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output indent="yes" /> 

    <xsl:template match="/"> 
    <doc><xsl:apply-templates select="doc/page" /></doc> 
    </xsl:template> 

    <xsl:template match="page"> 
    <page><xsl:apply-templates select="elem[1]" /></page> 
    </xsl:template> 

    <!-- an element whose value is the same as the next one - don't output 
     anything now, just increment counter for the next elem --> 
    <xsl:template match="elem[. = following-sibling::elem[1]]"> 
    <xsl:param name="count" select="1" /> 
    <xsl:apply-templates select="following-sibling::elem[1]"> 
     <xsl:with-param name="count" select="$count + 1" /> 
    </xsl:apply-templates> 
    </xsl:template> 

    <!-- otherwise - output element with current counter value and start again 
     from 1 for the next (if any) element --> 
    <xsl:template match="elem"> 
    <xsl:param name="count" select="1" /> 
    <elem c="{$count}"><xsl:value-of select="." /></elem> 
    <xsl:apply-templates select="following-sibling::elem[1]" /> 
    </xsl:template> 

</xsl:stylesheet> 

page模板应用模板只是第一elem,每个elem随后负责处理下一个在链中。