Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSLT to sort nodes by name?

Tags:

sorting

xml

xslt

I'm unsure how the xsl:sort directive works. I need to sort elements by their tag name (for diffing), and I can't seem to come up with how to make this work. My first though was to modify the identity transform and just modify it to include a sort statement, but I'm not exactly sure how to do that.

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()">
              <!-- xsl:sort ? -->
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

like image 997
Stefan Kendall Avatar asked Nov 03 '10 19:11

Stefan Kendall


1 Answers

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="@*">
    <xsl:sort select="name()"/>
   </xsl:apply-templates>

   <xsl:apply-templates select="node()">
    <xsl:sort select="name()"/>
   </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

when applied on this XML document:

<t b="x" c="y" a="t">
  <c/>
  <b/>
  <a/>
</t>

produces the wanted sorted output:

<t a="t" b="x" c="y">
    <a></a>
    <b></b>
    <c></c>
</t>

Do note:

  1. Not only the elements but also the attributes are sorted (the latter is implementation dependent, but works OK with MSXML).

  2. Using sorted XML for diffs is unreliable, because converting an XML document to a sorted representation isn't 1:1 mapping.

like image 88
Dimitre Novatchev Avatar answered Sep 18 '22 20:09

Dimitre Novatchev