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 |