|
Subject: RE: [xsl] Re: Dynamic number of sort key component? From: "Michael Kay" <mike@xxxxxxxxxxxx> Date: Fri, 14 May 2010 15:22:24 +0100 |
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: [xsl] 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 |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| [xsl] Re: Dynamic number of sort ke, Fabre Lambeau | Thread | Re: [xsl] Re: Dynamic number of sor, Dimitre Novatchev |
| Re: [xsl] xsl:key, predicates and d, David Carlisle | Date | [xsl] xslt 2.1 saxon:discard-docume, Andrew Welch |
| Month |