Use:
<xsl:apply-templates select="node">
<xsl:sort select="not(val1 = val2)"/>
</xsl:apply-templates>
Here is a complete example. This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<t>
<xsl:apply-templates select="node">
<xsl:sort select="not(val1 = val2)"/>
</xsl:apply-templates>
</t>
</xsl:template>
<xsl:template match="node[not(val1 = val2)]">
<div>
<node>
<xsl:apply-templates/>
</node>
</div>
</xsl:template>
</xsl:stylesheet>
when applied on this XML document:
<t>
<node>
<val1>1</val1>
<val2>2</val2>
</node>
<node>
<val1>3</val1>
<val2>3</val2>
</node>
</t>
produces the wanted, correct result:
<t>
<node>
<val1>3</val1>
<val2>3</val2>
</node>
<div>
<node>
<val1>1</val1>
<val2>2</val2>
</node>
</div>
</t>
Explanation of the solution:
Whenever an <xsl:apply-templates>
has an <xsl:sort>
child, the nodes that are selected are sorted according the data provided in the <xsl:sort>
child(ren) and the results of applying templates on each selected node appear in the output in that (sort) order -- not in document order.
In the transformation above we have:
<xsl:apply-templates select="node">
<xsl:sort select="not(val1 = val2)"/>
</xsl:apply-templates>
This means that the results of applying templates to the elements named node
for which it is true that val1=val2
will appear before the results of applying templates to the elements named node
for which val1=val2
is not true. This is because false
sorts before true
.
If this explanation is not clear, the reader is directed to read more about <xsl:sort>
.