Subject: [xsl] Re: Re: Can grouping and sorting be done in single transformation? From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx> Date: Tue, 18 Nov 2003 23:14:12 +0100 |
"Herman Kwok" <herman.kwok@xxxxxxxxxxxxxxxx> wrote in message news:20031118102107.7888.qmail@xxxxxxxxxxxx > Sorry for my late reply as I was out of town. > > Thanks Dimitre for the "exslt:node-set()" solution and Jarkko for the "xalan:nodeset()" solution. > > Does it mean that there is no solution without using processor dependent solution nor external library in XSLT 1.0? No. > > Well, I am new to XSLT. I suspect that there are some limitations in node set in XSLT. That was why the function was extended via > using external library or via enhancing a processor. Am I correct? No. Actually it has been proven that XSLT is Turing-complete. This means that any algorithm, that can be implemented on a Turing machine (or on a programming system that is as powerful or less than a Turing machine) can be implemented in XSLT. However, not using the xxx:node-set() extension function would be a little more difficult and probably a little bit less efficient. Here is a solution that does not use any extension functions. This transformation: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:param name="pNumInGroup" select="3"/> <xsl:key name="kfromID" match="item" use="generate-id()"/> <xsl:template match="/"> <xsl:variable name="vIDs"> <xsl:for-each select="/*/item"> <xsl:sort select="@desc"/> <xsl:value-of select="concat(generate-id(), '|')"/> </xsl:for-each> </xsl:variable> <xsl:call-template name="group"> <xsl:with-param name="pIDs" select="$vIDs"/> <xsl:with-param name="pNumInGroup" select="$pNumInGroup"/> </xsl:call-template> </xsl:template> <xsl:template name="group"> <xsl:param name="pIDs" /> <xsl:param name="pNumInGroup" select="1"/> <xsl:if test="contains($pIDs, '|')"> <group> <xsl:call-template name="fillElements"> <xsl:with-param name="pIDs" select="$pIDs"/> <xsl:with-param name="pNumInGroup" select="$pNumInGroup"/> </xsl:call-template> </group> <xsl:variable name="vOffset"> <xsl:call-template name="getOffset"> <xsl:with-param name="pIDs" select="$pIDs"/> <xsl:with-param name="pNumInGroup" select="$pNumInGroup"/> </xsl:call-template> </xsl:variable> <xsl:call-template name="group"> <xsl:with-param name="pIDs" select="substring($pIDs, $vOffset + 1)"/> <xsl:with-param name="pNumInGroup" select="$pNumInGroup"/> </xsl:call-template> </xsl:if> </xsl:template> <xsl:template name="fillElements"> <xsl:param name="pIDs"/> <xsl:param name="pNumInGroup" select="1"/> <xsl:if test="$pNumInGroup > 0 and contains($pIDs, '|')"> <xsl:copy-of select="key('kfromID', substring-before($pIDs, '|'))"/> <xsl:call-template name="fillElements"> <xsl:with-param name="pIDs" select="substring-after($pIDs, '|')"/> <xsl:with-param name="pNumInGroup" select="$pNumInGroup - 1"/> </xsl:call-template> </xsl:if> </xsl:template> <xsl:template name="getOffset"> <xsl:param name="pIDs"/> <xsl:param name="pNumInGroup" select="1"/> <xsl:param name="pResult" select="0"/> <xsl:choose> <xsl:when test="$pNumInGroup > 0 and contains($pIDs, '|')"> <xsl:variable name="vT1" select="substring-before($pIDs, '|')"/> <xsl:call-template name="getOffset"> <xsl:with-param name="pIDs" select="substring-after($pIDs, '|')"/> <xsl:with-param name="pNumInGroup" select="$pNumInGroup - 1"/> <xsl:with-param name="pResult" select="$pResult + string-length(substring-before($pIDs, '|')) + 1"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$pResult"/> </xsl:otherwise> </xsl:choose> </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: <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> ===== Cheers, Dimitre Novatchev. http://fxsl.sourceforge.net/ -- the home of FXSL XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Vertical lines, Skwirel Software Ltd | Thread | [xsl] A new approach, Kevin Waterson |
Re: [xsl] Re: XPATH, poppe chris | Date | Re: [xsl] Re: XPATH, poppe chris |
Month |