将XSLT分组并排序成多列

时间:2011-10-04 18:04:34

标签: xslt-2.0 xslt-grouping

我有一份XML动物列表。我想按类对它们进行分组,并在包含三行的表中显示它们。我可以使用XSLT 2.0和for-each-group

来实现这一目标
<zoo>
<animal class="fish">Koi</animal>
<animal class="fish">Lamprey</animal>
<animal class="bird">Chicken</animal>
<animal class="fish">Firefish</animal>
<animal class="fish">Bluegill</animal>
<animal class="bird">Eagle</animal>
<animal class="fish">Eel</animal>
<animal class="bird">Osprey</animal>
<animal class="bird">Turkey</animal>
<animal class="fish">Guppy</animal>
</zoo>

XSLT是:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" name="html" doctype-system="about:legacy-compat" />
<xsl:template match="/">
<html><head></head><body>
      <xsl:for-each-group select="//animal" group-by="@class">
        <table>
            <xsl:for-each-group select="current-group()" group-adjacent="ceiling(position() div 3)">
           <tr>
               <xsl:for-each select="current-group()">
                   <xsl:apply-templates select="."/>
               </xsl:for-each>
            </tr>
        </xsl:for-each-group>
        </table>
      </xsl:for-each-group>
    </body></html>
</xsl:template>

<xsl:template match="animal">
  <td><xsl:value-of select="."/></td>
</xsl:template>

</xsl:stylesheet>

除了我需要对动物名称进行排序之外,输出几乎是完美的。

我尝试使用&lt; xsl:perform-sort select =“current-group()”&gt;就像迈克尔凯向某人here建议的那样。但这导致了堆栈溢出。我有什么想法可以在我的分组列表和多列表列表中对动物名称进行排序?

2 个答案:

答案 0 :(得分:0)

<xsl:for-each>

中添加排序标记
<xsl:for-each select="current-group()">
    <xsl:sort data-type="text" select="." order="ascending"/>
    <xsl:apply-templates select="."/>
</xsl:for-each>

答案 1 :(得分:0)

这是一个有效的解决方案(虽然我不确定我理解为什么)。

<xsl:variable name="unsorted" select="current-group()"/>
<xsl:variable name="sorted">
  <xsl:perform-sort select="current-group()">
    <xsl:sort select="."/>
  </xsl:perform-sort>
</xsl:variable>
<xsl:for-each-group select="$sorted/animal" group-adjacent="ceiling(position() div 3)">
   <tr>
   <xsl:for-each select="current-group()">
     <xsl:apply-templates select="."/>
   </xsl:for-each>
   </tr>
</xsl:for-each-group>

(当然你不需要任何“未分类”变量。它只是用于比较)

奇怪的是,如果我在for-each-group中使用$ unsorted,它就像我期望的那样构建未排序的列表。但是,如果我使用$ sorted,我必须使用“$ sorted / animal”,原因我不太明白。