使用XSLT 3.0按字母顺序排列KML地标

问题描述 投票:0回答:1

我正在尝试按字母顺序对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。

欢呼声

xml xslt kml saxon xslt-3.0
1个回答
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。


0
投票

一种非常基本的方法是在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>
© www.soinside.com 2019 - 2024. All rights reserved.