ycomp
ycomp

Reputation: 8563

sort XML tags into alphabetical order

anyone know of a way that I can load an XML file into and sort it and then save the file?

I have a xml file with a bunch of settings.. and now it is getting hard to manage because they are not in any natural sort order...

e.g.

<edit_screen_a>
<settings_font_size>
<edit_screen_b>
<display_screen>
<settings_font_name>

to sort to:

<display_screen>
<edit_screen_a>
<edit_screen_b>
<settings_font_name>
<settings_font_size>

Upvotes: 10

Views: 25131

Answers (2)

Jobin Jacob Kavalam
Jobin Jacob Kavalam

Reputation: 141

If the accepted answer is giving you problems, consider this:

sort.xslt

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- for well formatted output -->
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="*">
        <!-- copy this node (but this does not copy the attributes ...) -->
        <xsl:copy>
            <!-- so, copy the attributes as well -->
            <xsl:copy-of select="@*"/>
            <!-- recurse on sorted (by tag name) list of child nodes -->
            <xsl:apply-templates>
                <xsl:sort select="name()"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

(Reference documentation on XSLT including the various operations used above may be found on MDN)

Compared to https://stackoverflow.com/a/9165464/5412249

  • does not assume any particular root node
  • preserves the attributes as well
  • uses a single template (and IMHO more easier to understand)

To actually apply this, on a Mac (and presumably on linux systems as well), you may use xsltproc

xsltproc sort.xslt test.xml

where, test.xml is any arbitrary xml file

Upvotes: 1

Daniel Haley
Daniel Haley

Reputation: 52848

You could use XSLT and run it from the command line. (I'd recommend Saxon, but Xalan would be ok.)

Here's an example...

XML Input

<doc>
  <edit_screen_a/>
  <settings_font_size/>
  <edit_screen_b/>
  <display_screen/>
  <settings_font_name/>
</doc>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:template match="doc">
    <doc>
      <xsl:apply-templates>
        <xsl:sort select="name()"/>
      </xsl:apply-templates>      
    </doc>
  </xsl:template>

</xsl:stylesheet>

XML Output

<doc>
   <display_screen/>
   <edit_screen_a/>
   <edit_screen_b/>
   <settings_font_name/>
   <settings_font_size/>
</doc>

Upvotes: 9

Related Questions