Hi Derek,
I have tried, in my code to have:
<xsl:for-each select="file">
<xsl:choose>
<xsl:when test="$sort='design'"><xsl:sort
select="name"/></xsl:when>
<xsl:when test="$sort='stat'"><xsl:sort
select="status"/></xsl:when>
<xsl:otherwise><xsl:sort select="id"/></xsl:otherwise>
</xsl:choose>
As has been pointed out to you, you can't have <xsl:sort> elements
wrapped in a <xsl:choose> -- they must be the first, direct, children
of <xsl:for-each>.
The difficulty, then, is to select a different thing to sort by
depending on the value of the $sort variable. You've been shown a
couple of ways to do this. Another way is:
<xsl:for-each select="file">
<xsl:sort select="name[$sort = 'design'] |
status[$sort = 'stat'] |
id[$sort != 'design' and $sort != 'stat']" />
...
</xsl:for-each>
This selects a node-set containing the <name> element child of <file>,
but only if $sort is 'design', the <status> element, but only if $sort
is 'stat', and the <id> element, but only if $sort is neither 'design'
nor 'stat'. Since the three conditions are mutually exclusive, you end
up with a node-set containing the single node that you want.
The advantage of this method is that the paths that select the nodes
you want can be anything at all -- they don't all have to be children
of the nodes you're sorting, for example.
Of course, in XSLT 2.0, things become a lot clearer. You can use the
if expression in XPath 2.0 as follows:
<xsl:for-each select="file">
<xsl:sort select="if ($sort = 'design') then name
else if ($sort = 'stat') then status
else id" />
...
</xsl:for-each>
Or if you prefer you can use an <xsl:choose> inside the <xsl:sort>, as
in:
<xsl:for-each select="file">
<xsl:sort>
<xsl:choose>
<xsl:when test="$sort = 'design'">
<xsl:sequence select="name" />
</xsl:when>
<xsl:when test="$sort = 'stat'">
<xsl:sequence select="status" />
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="id" />
</xsl:otherwise>
</xsl:choose>
</xsl:sort>
...
</xsl:for-each>
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/