Используйте
<xsl:apply-templates select="node">
<xsl:sort select="not(val1 = val2)"/>
</xsl:apply-templates>
Вот полный пример. Это преобразование:
<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>
при применении к этому документу XML :
<t>
<node>
<val1>1</val1>
<val2>2</val2>
</node>
<node>
<val1>3</val1>
<val2>3</val2>
</node>
</t>
дает желаемый, правильный результат:
<t>
<node>
<val1>3</val1>
<val2>3</val2>
</node>
<div>
<node>
<val1>1</val1>
<val2>2</val2>
</node>
</div>
</t>
Объяснение решения :
Всякий раз, когда <xsl:apply-templates>
имеет дочерний элемент <xsl:sort>
, выбранные узлы сортируются в соответствии с данными, предоставленными в дочернем <xsl:sort>
(ren), и результаты применения шаблонов для каждого выбранного узла отображаются в выходных данных в этот (сортировка) порядок - не в порядке документа.
В приведенном выше преобразовании имеем:
<xsl:apply-templates select="node">
<xsl:sort select="not(val1 = val2)"/>
</xsl:apply-templates>
Это означает, что результаты применения шаблонов к элементам с именем node
, для которых верно, что val1=val2
будут появляться до результатов применения шаблонов к элементам с именем node
, для которых val1=val2
не соответствует действительности. , Это потому что false
сортирует до true
.
Если это объяснение неясно, читателю предлагается прочитать больше о <xsl:sort>
.