Sorting XML file by element -
i want sort xml file elements in same level alphabetically. means, sorting elements on first level, inside every element subelement , on recursively. must multilevel, not 1 level (that solved in other question). example (please ignore content , meaning):
<example> <note> <to>tove</to> <from>jani</from> <heading>reminder</heading> <headb>head</head3> <heada>head</head3> <body>don't forget me weekend!</body> </note> <next> <c>blabla</c> <a>blabla</a> </next> </example>
to:
<example> <next> <a>blabla</a> <c>blabla</c> </next> <note> <body>don't forget me weekend!</body> <from>jani</from> <heading>reminder</heading> <heada>head</head3> <headb>head</head3> <to>tove</to> </note> </example>
the xml can contain thousands of lines , many levels of elements
you should able use identity transform , add xsl:sort
sort on either name()
or local-name()
.
example...
xml input (well formed , more complicated original.)
<example> <note> <to>tove</to> <from>jani</from> <heading>reminder</heading> <headb>head</headb> <heada>head</heada> <body>don't forget me weekend!</body> </note> <next> <c>blabla</c> <a>blabla</a> </next> <djh> <!-- comment --> <foo attr="test"> <bar> <baz>text</baz> <foo><!--comment--></foo> </bar> <baz attr="test"> <foo/> <bar/> </baz> </foo> <?pi?> <baz> <bar> <foo/> <baz/> </bar> <foo> <bar/> <baz/> </foo> </baz> </djh> </example>
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:sort select="local-name()"/> </xsl:apply-templates> </xsl:copy> </xsl:template> </xsl:stylesheet>
xml output
<example> <djh><!-- comment --><?pi?> <baz> <bar> <baz/> <foo/> </bar> <foo> <bar/> <baz/> </foo> </baz> <foo attr="test"> <bar> <baz>text</baz> <foo><!--comment--></foo> </bar> <baz attr="test"> <bar/> <foo/> </baz> </foo> </djh> <next> <a>blabla</a> <c>blabla</c> </next> <note> <body>don't forget me weekend!</body> <from>jani</from> <heada>head</heada> <headb>head</headb> <heading>reminder</heading> <to>tove</to> </note> </example>
notice though comments , processing instructions end floating top of sort order.
also note if have mixed content (element , text nodes in same parent), might want skip sorting of element. otherwise text come first in sort order (like comments , processing instructions).
here's way skip mixed content elements (comment , processing instruction output change may want experiment):
<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="*[not(text())]"> <xsl:copy> <xsl:apply-templates select="@*|node()"> <xsl:sort select="local-name()"/> </xsl:apply-templates> </xsl:copy> </xsl:template> </xsl:stylesheet>
Comments
Post a Comment