RE: [xsl] order-by vs xsl:sort

Subject: RE: [xsl] order-by vs xsl:sort
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 29 Apr 2005 13:37:04 +0100
The XQuery spec describes the semantics of sorting in terms of a stream of
tuples - that is, it requires data structures outside the scope of the
XPath/XQuery/XSLT data model. If it had been possible to describe the
semantics without straying outside the data model, I think someone would
have found a way of doing so. And if it requires extensions to the data
model, then I suspect that mechanical translation into XSLT is quite
difficult.

Am I right in thinking that your translation models the stream of N tuples
of width M as a sequence of length N*M, and then computes the sort key of
each item in a way that ensures that all the M items corresponding to a
single tuple get the same sort key, and therefore remain together when
sorted?

Another way of doing this sort might be to use xsl:for-each-group to treat
each tuple as a group, so that the sort key is only computed for the first
item in the group.

The question I'm more interested in is: is this feature useful to anyone?

 

> -----Original Message-----
> From: David Carlisle [mailto:davidc@xxxxxxxxx] 
> Sent: 29 April 2005 12:43
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] order-by vs xsl:sort
> 
> 
> 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:
> 
> $ saxon8 -it x order.xsl
> <?xml version="1.0" encoding="UTF-8"?>
> es ds et cs dt eu bs ct du as bt cu at bu au
> 
> and I think would be automatically generatable in an xquery to xslt
> conversion program, although the indexes get messy if there are more
> sequences than two involved, and the constraints on xsl:sort 
> being first
> mean that you can't make it look nicer by using variables to hold the
> calculated indices.
> 
> Is this approach plausible? and if so can it be made a bit less ugly?
> If not, is there a more plausible approach?
> 
> David
> 
> ______________________________________________________________
> __________
> This e-mail has been scanned for all viruses by Star. The
> service is powered by MessageLabs. For more information on a proactive
> anti-virus service working around the clock, around the globe, visit:
> http://www.star.net.uk
> ______________________________________________________________
> __________

Current Thread