列出由xslt返回的组元素

时间:2011-05-02 20:12:49

标签: xslt-grouping

您好我有以下xml

<?xml version="1.0" encoding="UTF-8"?>
<root>
<item>
<name>john</name>
<year>2010</year>
</item>
<item>
<name>sam</name>
<year>2000</year>
</item>
<item>
<name>jack</name>
<year>2007</year>
</item>
<item>
<name>smith</name>
<year>2010</year>
</item>
</root>

我使用以下xslt按年分组

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
<xsl:template match="/">
<xsl:for-each-group select="r//*[(name=*)]" group-by="year">
<xsl:sort select="year" order="descending"/>
<xsl:variable name="total" select="count(/r//*[(name=*)]) + 1" />
    <xsl:value-of select="year"/><br />
    <xsl:for-each select="current-group()/name">
        <xsl:variable name="i" select="position()"/>    
        <xsl:call-template name="row">
            <xsl:with-param name="name" select="."/>
            <xsl:with-param name="number" select="$total - $i"/>
        </xsl:call-template>
    </xsl:for-each>
    <br />
</xsl:for-each-group>
</xsl:template>

<xsl:template name="row">
<xsl:param name="name"/>
<xsl:param name="number"/>
        <xsl:value-of select="concat($number, '. ')"/>
        <xsl:value-of select="concat($name, ' ')"/><br />
</xsl:template>
</xsl:stylesheet>

这是输出,它非常接近我想要的输出。

2010 
4. john 
3. smith 

2007 
4. jack 

2000
4. sam

我想要的只是简单地编号所有名称(从名称总数降序为1),例如

2010
4. john 
3. smith 

2007
2. jack 

2000
1. sam

如果我们可以将varible重新分配给新值,那将很简单,但我认为这是不可能的,所以我必须找到另一种解决方案。任何人都可以帮我找到解决这个问题的方法。

感谢

1 个答案:

答案 0 :(得分:0)

这是一个XSLT-1.0解决方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output type="text" omit-xml-declaration="yes"/>
    <xsl:key name="byYear" match="item" use="year"/>
    <xsl:template match="/">
        <!-- process first item for each distinct year number (ordered) -->
        <xsl:apply-templates select="//item[count(.|key('byYear',year)[1])=1]">
            <xsl:sort select="year" order="descending"/>
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="item">
        <!-- output year number, surrounded by newlines -->
        <xsl:text>
</xsl:text>
        <xsl:value-of select="year"/>
        <xsl:text>
</xsl:text>
        <!-- now process all items for the current year number -->
        <xsl:for-each select="key('byYear',year)">
            <!-- output reversed index of current item for current year number
                 plus total items for lower year numbers -->
            <xsl:number value="count(//item[year &lt; current()/year])+last()-position()+1"
                 format="1. "/>
            <!-- and finally also the name of the current item and again a newline -->
            <xsl:value-of select="name"/>
            <xsl:text>
</xsl:text>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>