|
Subject: Re: [xsl] Re: Dynamic number of sort key component? From: Fabre Lambeau <fabre.lambeau@xxxxxxxxx> Date: Sun, 16 May 2010 08:45:58 +0100 |
How could I not think of it myself, it seems obvious now... I'm
forgetting my basics clearly...
Luckily, I get to use XSLT 2.0 these days (a blessing!), so did not
have to go for Dimitre's solution.
I reckon however that the last expression needs to be changed from
subsequence($sortColumnNames,
2) to $sortColumnNames[position() < last()] to get them ordered
correctly (last component first processed)
Many thanks!
On 14 May 2010 15:22, Michael Kay <mike@xxxxxxxxxxxx> wrote:
>
> Try something like this:
>
> <xsl:function name="f:sort" as="element(row)*">
> B <xsl:param name="data" as="element(row)"/>
> B <xsl:param name="sortColumnNames" as="xs:string*"/>
> B <xsl:param name="sortAscDesc" as="xs:string*"/>
> B <xsl:variable name="sorted" as="element(row)">
> B B <xsl:perform-sort select="$data">
> B B B <xsl:sort select="*[name()=$sortColumnNames[last()]"
> B B B B B B B B order="{$sortAscDesc[last()]}" stable="yes"/>
> B B </xsl:perform-sort>
> B <xsl:variable>
> B <xsl:sequence select="if (count($sortColumnNames) eq 1
> B B B B B B B B B B B B then $sorted
> B B B B B B B B B B B B 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>
>> B <row>
>> B B <col name="a">1</col>
>> B B <col name="b">2</col>
>> B B <col name="c">3</col>
>> B B <col name="d">4</col>
>> B </row>
>> B <row>
>> B B <col name="a">bla</col>
>> B B <col name="b">bli</col>
>> B B <col name="c">blo</col>
>> B B <col name="d">blu</col>
>> B </row>
>> B <!-- ... -->
>> </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">
>> B <xsl:for-each select="tokenize($group-by, ',')">
>> B B <xsl:sort select="col[@name=string-before(current(),' '])
>> order="{string-after(current(),' ']}ending"/>
>> B </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
>
>
--
Fabre Lambeau
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| Re: [xsl] Re: Dynamic number of sor, Dimitre Novatchev | Thread | RE: [xsl] Re: Dynamic number of sor, Michael Kay |
| [xsl] .NET 4.0 XslCompiledTransform, Max Toro | Date | RE: [xsl] First public working draf, Vladimir Nesterovsky |
| Month |