This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 4400 - Allow xsl:variable before xsl:sort
Summary: Allow xsl:variable before xsl:sort
Status: CLOSED DUPLICATE of bug 5166
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 (show other bugs)
Version: Recommendation
Hardware: PC Windows XP
: P2 enhancement
Target Milestone: ---
Assignee: Michael Kay
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords: futureConsideration
Depends on:
Blocks:
 
Reported: 2007-03-20 14:59 UTC by viktor_b_68
Modified: 2014-05-15 14:00 UTC (History)
0 users

See Also:


Attachments

Description viktor_b_68 2007-03-20 14:59:32 UTC
The XSLT recommendation at http://www.w3.org/TR/xslt#element-sort specifies that "When used in xsl:for-each, xsl:sort elements must occur first."
That is generally a good rule, but I suggest an exception should be made for xsl:variable (and possibly others that do not generate content), allowing that element to appear before xsl:sort.
Because the purpose of variables is to avoid having to print similar code many times.
But as seen in the examples, due to the current restricion, you have to print out a long complex search path twice.
In the second (conceptual) example, you could first assign a node to a variable, then use it in the xsl:sort element already.
The result is a much cleaner document, that is easier to maintain.


<xsl:for-each select="/foo/bar">
	<xsl:sort select="document('items.xml')//item[@xml:id = current()/@code]/@label" />
	<xsl:variable name="item" select="document('items.xml')//item[@xml:id = current()/@code]" />  <!-- unnecessary repetion -->
	<xsl:value-of select="$item/@a" />
	...
	<xsl:value-of select="$item/@z" />
</xsl:for-each>


<xsl:for-each select="/foo/bar">
	<xsl:variable name="item" select="document('items.xml')//item[@xml:id = current()/@code]" />  <!-- only written once -->
	<xsl:sort select="$item/@label" />
	<xsl:value-of select="$item/@a" />
	...
	<xsl:value-of select="$item/@z" />
</xsl:for-each>
Comment 1 Michael Kay 2007-03-20 16:41:57 UTC
Thanks for the comment. We haven't really started any serious work yet towards gathering requirements for a future version of XSLT, but no doubt this suggestion will get added into the list for consideration. 

The idea seems to take one a step closer to reproducing the XQuery FLWOR expression in XSLT. In XQuery it would be written:

for $x in /foo/bar
let $item := document('items.xml')//item[@xml:id = $x/@code]
order by $item/label
return $item/@a, $item/@z

In your particular example (and in most practical examples) I think there are straightforward workarounds. Here I would do:

<xsl:key name="k" match="item" use="@xml:id"/>

then

<xsl:for-each select="/foo/bar/key('k', @code, document('items.xml'))">
<xsl:sort select="label"/>
<xsl:value-of select="@a"/>
<xsl:value-of select="@z"/>

This is a personal response.
Comment 2 Sharon Adler 2007-04-17 14:24:38 UTC
This will be keep for possible consideration as a future enhancement.
Comment 3 Michael Kay 2008-09-05 13:42:12 UTC

*** This bug has been marked as a duplicate of bug 5166 ***