我正在尝试按字母顺序对KML文档中的地标元素进行排序。该文档包含多个我不想重新排序的Folder元素。我只需要对每个文件夹内的地标进行排序。
样本输入:
<?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>
预期输出:
<?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>
我已经尝试了以下XSLT 3.0样式表:
<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>
它什么也没做。我正在尝试使用XSLT 3.0,因为它是最新的规格。我正在使用Saxon运行转换(以防万一):
java -jar Saxon-HE-10.0.jar -s:source.kml -xsl:sort.xsl -o:output.kml
[如果有人知道如何使用XSLT 1.0或2.0做到这一点,我会接受,但我更喜欢XSLT 3.0。
欢呼声
[从撒克逊10号开始,例如match="Folder"
匹配名称空间http://www.opengis.net/kml/2.2
中的元素,可以使用命令行选项-ns:http://www.opengis.net/kml/2.2
,请参见http://saxonica.com/html/documentation/using-xsl/commandline/。
当然,在XSLT 2和更高版本中,您也可以在xpath-default-namespace="http://www.opengis.net/kml/2.2"
元素上设置xsl:stylesheet
。
perform-sort
似乎与Folder/Placemark
的选择有误,我认为应该是Placemark
,但是仅对Placemark
元素进行排序的任务可能仍无法解决您设置模板的方式。解决方案的复杂度取决于输入的可能复杂度,Placemark
元素是否可以与其他子元素混合;如果您知道所有其他元素都将在地标子元素之前,则可以使用
<xsl:template match="Folder">
<xsl:copy>
<xsl:apply-templates select="* except Placemark, sort(Placemark, (), function($p) { $p/name })"/>
</xsl:copy>
</xsl:template>
在XSLT 3中,以及使用Saxon 10 HE或Saxon的早期版本,但使用PE或EE。
一种非常基本的方法是在xsl:stylesheet
元素上定义一个名称空间并使用它(“ select”表达式错误):
<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:perform-sort select="kml:Placemark">
<xsl:sort select="kml:name" data-type="text" order="ascending"/>
</xsl:perform-sort>
</xsl:template>
</xsl:stylesheet>