Hi am build a generic template to list my content. But the Content may be sorted on different @\'s or node()\'s. So want to pass the xPath in.
The |
(union operator) works... I must have gotten it slightly wrong when tried before. It was @Dimitre Novatchev's answer lead me down the right path!!
The following works:
<xsl:sort select="@*[name()=$sort] | *[name()=$sort]"
order="{$order}" data-type="text"/>
It allows me to sort on attributes and nodes. Obviously, as long as they don't have the same name()
but different values.
This is by design. The select
attribute is the only one which doesnt accept AVTs (Attribute - Value Templates).
The usual solution is to define a variable with the name of the child element that should be used as sort key. Below is a small example:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vsortKey" select="'b'"/>
<xsl:variable name="vsortOrder" select="'descending'"/>
<xsl:template match="/*">
<xsl:for-each select="*">
<xsl:sort select="*[name() = $vsortKey]" order="{$vsortOrder}"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the following XML document:
<t>
<a>
<b>2</b>
<c>4</c>
</a>
<a>
<b>5</b>
<c>6</c>
</a>
<a>
<b>1</b>
<c>7</c>
</a>
</t>
the wanted result is produced:
<a>
<b>5</b>
<c>6</c>
</a>
<a>
<b>2</b>
<c>4</c>
</a>
<a>
<b>1</b>
<c>7</c>
</a>