[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
Re: [xsl] order-by vs xsl:sort
Subject: Re: [xsl] order-by vs xsl:sort From: Dimitre Novatchev <dnovatchev@xxxxxxxxx> Date: Fri, 29 Apr 2005 23:30:40 +1000 |
On 4/29/05, David Carlisle <davidc@xxxxxxxxx> wrote: > > I've been toying to see how to express xquery's order by in terms of > xsl. (There's a question at the end, bonus points for anyone not called > Michael who even gets that far:-) > > here's an example xquery > > let $data1:= > <a> > <z id="a"><y id="1"/></z> > <z id="b"><y id="2"/></z> > <z id="c"><y id="3"/></z> > <z id="d"><y id="4"/></z> > <z id="e"><y id="5"/></z> > </a> > return > let $data2:= > <a> > <z id="s"><y id="6"/></z> > <z id="t"><y id="7"/></z> > <z id="u"><y id="8"/></z> > </a> > return > > for $i in $data1/z/y, $j in $data2/z/y > order by ($j/@id - $i/@id) > return > concat($i/../@id,$j/../@id) > > and here's its output (linebreak added after the xml delcn by hand) > > $ saxon8q order.xq > <?xml version="1.0" encoding="UTF-8"?> > es ds et cs dt eu bs ct du as bt cu at bu au > > Things to note about this are > a) the sort key cuts across the diagonal, you can't just sort the i and j > axes separately. So you can't simply make this into two nested > xsl:for-each each with separate xsl:sort's. > b) the final result uses data accessed by the parent axis from the items > in the sorted sequence so you can't simply build a temporary tree > that holds a sequence of elements modelling the tuple with copies of > the items in the sequence as then stuff in the parent axis is lost. > > Current best plan is the following XSL > > <?xml version="1.0" encoding="UTF-8"?> > <xsl:stylesheet > xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > version="2.0" > > > > <xsl:variable name="data1" as="item()"> > <a> > <z id="a"><y id="1"/></z> > <z id="b"><y id="2"/></z> > <z id="c"><y id="3"/></z> > <z id="d"><y id="4"/></z> > <z id="e"><y id="5"/></z> > </a> > </xsl:variable> > > <xsl:variable name="data2" as="item()"> > <a> > <z id="s"><y id="6"/></z> > <z id="t"><y id="7"/></z> > <z id="u"><y id="8"/></z> > </a> > </xsl:variable> > > <xsl:template name="x"> > > <xsl:variable name="is" select="$data1/z/y"/> > <xsl:variable name="ci" select="count($is)"/> > <xsl:variable name="js" select="$data2/z/y"/> > <xsl:variable name="cj" select="count($js)"/> > > <xsl:for-each select="0 to ($ci * $cj)-1"> > <xsl:sort select="$js[(current() idiv $ci) +1]/@id - $is[(current() mod $ci)+1]/@id"/> > <xsl:sequence select="concat($is[(current() mod $ci)+1]/../@id,$js[(current() idiv $ci) +1]/../@id)"/> > </xsl:for-each> > > </xsl:template> > > </xsl:stylesheet> > > which works: Isn't this simpler? <xsl:for-each select= "for $i in $data1/z/y, $j in $data2/z/y return concat($i/../@id, $j/../@id, string($j/@id - $i/@id)) "> <xsl:sort select="substring(.,3)"/> <xsl:sequence select="substring(.,1,2)"/> </xsl:for-each> Cheers, Dimitre Novatchev
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] order-by vs xsl:sort, Michael Kay | Thread | Re: [xsl] order-by vs xsl:sort, David Carlisle |
RE: [xsl] order-by vs xsl:sort, Michael Kay | Date | Re: [xsl] order-by vs xsl:sort, David Carlisle |
Month |