<xsl:apply-templates select="node() | @*">
<xsl:sort
select="text()"
order="descending" />
</xsl:apply-templates>
For attribute nodes the value of the sort key (child::text()) will always be
an empty sequence. An empty sequence sorts before any other value, so in
descending order it sorts last, and since the template with match="@*"
creates attribute nodes, you will be adding attributes to the parent after
the children, which is an error.
This behaviour is certainly correct, and I'm not sure which part of it you
are questioning.
Incidentally, if any of your child elements contains an embedded comment,
the sort will fail because text() selects more than one node, and it's an
error in 2.0 for the sort key to be a sequence longer than one (in 1.0 all
but the first are ignored).
Michael Kay
http://www.saxonica.com/
-----Original Message-----
From: Abel Braaksma [mailto:abel(_dot_)online(_at_)xs4all(_dot_)nl]
Sent: 16 January 2007 13:01
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] xsl:sort descending causes attribute nodes to
be created after children, causing an error
Hi XSLT'ers,
The following issue is easy to workaround, but I am wondering
if this is correct behavior after the XSLT 2 (or even 1)
recommendation.
With an xsl:apply-template that includes attribute nodes in
its select-attribute, and you apply an xsl:sort on the
children, then it happens that the attribute nodes are
created after the children when the order of xsl:sort is
descending. I tried google on this, but couldn't find
something useful.
The example below throws the following error:
"An attribute node (count) cannot be created after the
children of the containing element"
I did not try other parsers. The xslt employs a simple copy
idiom and sorts the rows of the input in $data. Call the XSLT
on itself to see the error or the results:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output indent="yes" />
<xsl:variable name="data">
<rows count="3">
<row>bbbb</row>
<row>aaaa</row>
<row>cccc</row>
</rows>
</xsl:variable>
<xsl:template match="/">
<xsl:apply-templates select="$data/*" />
</xsl:template>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<xsl:template match="rows">
<xsl:copy>
<xsl:apply-templates select="node() | @*">
<xsl:sort
select="text()"
order="descending" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Any thoughts on this? Is this behavior desired and/or
required, or is this the processor's mistake?
Btw: a possible workaround is to apply the attribute node first.
Cheers,
-- Abel Braaksma
http://www.nuntia.nl
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail:
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--