marko
marko

Reputation: 3776

Sort elements in XML-file

I have a file that looks something like this:

<xml>
 <person>
  <name>John</name>
  <age>33</age>
  <car>Yugo</car>
 </person>
 <person>
  <car>Tesla</car>
  <age>44</age>
  <name>Peter</name>
 </person>
<xml>

As some may notice the elements in aren't in the same order.

Does anyone have know of an übersimple xslt that just preserves the xml-contents but formats the in-file?

This would be the wanted output:

<xml>
 <person>
  <age>33</age>
  <car>Yugo</car>
  <name>John</name>
 </person>
 <person>
  <age>44</age>
  <car>Tesla</car>
  <name>Peter</name>
 </person>
<xml>

A file that has the same values in it's elements BUT has some sort of order (in this case sorted by element-name).

Upvotes: 2

Views: 2243

Answers (2)

Peter
Peter

Reputation: 1796

This XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes"/>

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

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

</xsl:stylesheet>

applied to this XML:

<?xml version="1.0" encoding="UTF-8"?>
<xml>
<person>
    <name>John</name>
    <age>33</age>
    <car>Yugo</car>
</person>
<person>
    <car>Tesla</car>
    <age>44</age>
    <name>Peter</name>
</person>
</xml>

gives this output:

<?xml version="1.0" encoding="UTF-8"?>
<xml>
<person>
    <age>33</age>
    <car>Yugo</car>
    <name>John</name>
</person>
<person>
    <age>44</age>
    <car>Tesla</car>
    <name>Peter</name>
</person>
</xml>

Upvotes: 2

toniedzwiedz
toniedzwiedz

Reputation: 18563

xsl:sort should do the trick when you tell it to sort by the value of local-name() function. Replace it with name() function if you want to account for namespace prefixes.

The following stylesheet copies all elements in literally any document and sorts their content alphabetically.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
    <xsl:template match="*">
        <xsl:copy>
            <xsl:apply-templates>
                <xsl:sort select="local-name()"></xsl:sort>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

It does not accout for attributes, comments or CDATA but it shouldn't be a problem to implement these if you want.

Upvotes: 3

Related Questions