I am trying to sort alphabetically Placemark elements in a KML document. The document contains multiple Folder elements which I do not want to reorder. I only need to sort the Placemarks inside each Folder.
Sample input:
<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<name>Test</name>
<Folder>
<name>Zulu</name>
<Placemark>
<name>Bravo</name>
<Point>
<coordinates>
20,30,0
</coordinates>
</Point>
</Placemark>
<Placemark>
<name>Alfa</name>
<Point>
<coordinates>
10,20,0
</coordinates>
</Point>
</Placemark>
</Folder>
<Folder>
<name>Yankee</name>
<Placemark>
<name>Delta</name>
<Point>
<coordinates>
40,50,0
</coordinates>
</Point>
</Placemark>
<Placemark>
<name>Charlie</name>
<Point>
<coordinates>
30,40,0
</coordinates>
</Point>
</Placemark>
</Folder>
</Document>
</kml>
Expected output:
<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<name>Test</name>
<Folder>
<name>Zulu</name>
<Placemark>
<name>Alfa</name>
<Point>
<coordinates>
10,20,0
</coordinates>
</Point>
</Placemark>
<Placemark>
<name>Bravo</name>
<Point>
<coordinates>
20,30,0
</coordinates>
</Point>
</Placemark>
</Folder>
<Folder>
<name>Yankee</name>
<Placemark>
<name>Charlie</name>
<Point>
<coordinates>
30,40,0
</coordinates>
</Point>
</Placemark>
<Placemark>
<name>Delta</name>
<Point>
<coordinates>
40,50,0
</coordinates>
</Point>
</Placemark>
</Folder>
</Document>
</kml>
I have tried the following XSLT 3.0 stylesheet:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output name="xml"/>
<xsl:mode on-no-match="shallow-copy" />
<xsl:template match="Folder">
<xsl:perform-sort select="Folder/Placemark">
<xsl:sort select="name" data-type="text" order="ascending"/>
</xsl:perform-sort>
</xsl:template>
</xsl:stylesheet>
It doesn't do anything. I am trying to use XSLT 3.0 since it is the latest spec. I am using Saxon to run the transform (in case it matters):
java -jar Saxon-HE-10.0.jar -s:source.kml -xsl:sort.xsl -o:output.kml
If someone knows how to do this with XSLT 1.0 or 2.0, I'll take it but I'd prefer XSLT 3.0.
Cheers
A very basic approach would be defining a namespace on the xsl:stylesheet
element and using it (the "select" expression has been wrong):
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:kml="http://www.opengis.net/kml/2.2">
<xsl:output name="xml"/>
<xsl:mode on-no-match="shallow-copy" />
<xsl:template match="kml:Folder">
<xsl:copy>
<xsl:copy-of select="* except kml:Placemark" />
<xsl:perform-sort select="kml:Placemark">
<xsl:sort select="kml:name" data-type="text" order="ascending"/>
</xsl:perform-sort>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>