Reputation: 3776
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
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
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