[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Re: Re: Can grouping and sorting be done in single

Subject: Re: Re: Re: Can grouping and sorting be done in single transformation?
From: "Herman Kwok" <herman.kwok@xxxxxxxxxxxxxxxx>
Date: Wed, 19 Nov 2003 17:05:35 +0800
group by in xsl
Dimitre, Thanks once again. It is simply great. I had tried to solves for days.

----- Original Message -----
From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx>
Date: Tue, 18 Nov 2003 23:14:12 +0100
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject:  Re: Re: Can grouping and sorting be done in single    transformation?


"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


-- 
__________________________________________________________
Sign-up for your own personalized E-mail at Mail.com
http://www.mail.com/?sr=signup

Search Smarter - get the new eXact Search Bar for free!
http://www.exactsearchbar.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.