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

RE: Re: Dynamic number of sort key component?

Subject: RE: Re: Dynamic number of sort key component?
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 14 May 2010 15:22:24 +0100
RE:  Re: Dynamic number of sort key component?
Try something like this:

<xsl:function name="f:sort" as="element(row)*">
  <xsl:param name="data" as="element(row)"/>
  <xsl:param name="sortColumnNames" as="xs:string*"/>
  <xsl:param name="sortAscDesc" as="xs:string*"/>
  <xsl:variable name="sorted" as="element(row)">
    <xsl:perform-sort select="$data">
      <xsl:sort select="*[name()=$sortColumnNames[last()]" 
                order="{$sortAscDesc[last()]}" stable="yes"/>
    </xsl:perform-sort>
  <xsl:variable>
  <xsl:sequence select="if (count($sortColumnNames) eq 1 
                        then $sorted 
                        else f:sort($sorted, subsequence($sortColumnNames,
2), subsequence($sortAscDesc, 2))"/>
</xsl:function>

Those with grey hair will recognize this as the multi-phase sort process
used by punched card operators, sorting first by the last sort key, then the
last-but-one, and so on.

Regards,

Michael Kay
http://www.saxonica.com/
http://twitter.com/michaelhkay  

> -----Original Message-----
> From: Fabre Lambeau [mailto:fabre.lambeau@xxxxxxxxx] 
> Sent: 14 May 2010 14:46
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject:  Re: Dynamic number of sort key component?
> 
> I'm writing a tool that allows my users to query an XML 
> document a-la-SQL (but simplified).
> For example, given an XML document such as:
> 
> <table>
>   <row>
>     <col name="a">1</col>
>     <col name="b">2</col>
>     <col name="c">3</col>
>     <col name="d">4</col>
>   </row>
>   <row>
>     <col name="a">bla</col>
>     <col name="b">bli</col>
>     <col name="c">blo</col>
>     <col name="d">blu</col>
>   </row>
>   <!-- ... -->
> </table>
> 
> I'd like them to be able to say something like:
> SELECT a,b,c,d
> ORDER BY a ASC,b DESC
> GROUP BY a,c,d
> 
> My component (XSLT stylesheet) takes that query and 
> effectively processes it in XSLT.
> The GROUP BY statement is easy to process, since I can just 
> concatenate the values for the corresponding <col> elements, 
> and use that string as a key to a for-each-group.
> However, I can't find a way to do the sorting (for which the 
> order is different for each individual column).
> 
> What I seem to need is the ability to have a dynamic number 
> of sort key components, which as far as I know is not 
> possible The following is obviously not possible:
> <xsl:perform-sort select="col">
>   <xsl:for-each select="tokenize($group-by, ',')">
>     <xsl:sort select="col[@name=string-before(current(),' ']) 
> order="{string-after(current(),' ']}ending"/>
>   </xsl:for-each>
> </xsl:perform>
> 
> Can anyone think of a way to do this (whilst retaining the 
> ability to have a dynamic list of ORDER BY columns, each one 
> specifying its own order)?
> Unfortunately, I don't think I have the ability to generate a 
> separate XSLT sheet after parsing the query string and 
> execute it, as my engine is all in XSLT (executed with AltovaXML)
> 
> --
> Fabre Lambeau

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.