"Herman Kwok" <herman(_dot_)kwok(_at_)technologist(_dot_)com> wrote in message
news:20031110060052(_dot_)4077(_dot_)qmail(_at_)iname(_dot_)com(_dot_)(_dot_)(_dot_)
Hi all,
I am new to XSL. I am woundering if sorting and grouping can be done in
single transformation. If it is possible, would you please tell me how?
Yes, if you use the exslt:node-set() extension function.
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="ext"
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="result">
<xsl:copy>
<xsl:variable name="vrtfSorted">
<xsl:for-each select="item">
<xsl:sort select="@desc"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="vSorted"
select="ext:node-set($vrtfSorted)/*"/>
<xsl:for-each select="$vSorted">
<xsl:if test="position() mod 3 = 1">
<xsl:variable name="vPos" select="position()"/>
<group>
<xsl:copy-of select=". | $vSorted[position() > $vPos
and
position() < $vPos + 3
]"/>
</group>
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
when applied on your source.xml:
<result>
<item desc="d"/>
<item desc="j"/>
<item desc="k"/>
<item desc="e"/>
<item desc="c"/>
<item desc="g"/>
<item desc="h"/>
<item desc="i"/>
<item desc="f"/>
<item desc="a"/>
<item desc="b"/>
</result>
produces the wanted result:
<result>
<group>
<item desc="a"/>
<item desc="b"/>
<item desc="c"/>
</group>
<group>
<item desc="d"/>
<item desc="e"/>
<item desc="f"/>
</group>
<group>
<item desc="g"/>
<item desc="h"/>
<item desc="i"/>
</group>
<group>
<item desc="j"/>
<item desc="k"/>
</group>
</result>
=====
Cheers,
Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list