[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
Re: [xsl] Re: Dynamic number of sort key component?
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 |