使用XSLT将KML拆分为子文件,几乎在那里,但无法使其工作

时间:2011-07-27 14:26:54

标签: xml xslt kml

我有一个带国家边界的KML文件

    <Document>
    ...
        <Folder>
            <name>Countries</name>
            <Style>
                <ListStyle>
                    <listItemType>checkHideChildren</listItemType>
                    <bgColor>00ffffff</bgColor>
                    <maxSnippetLines>2</maxSnippetLines>
                </ListStyle>
            </Style>
            <Folder>
                <name>Labels</name>
                <Placemark>
                    <name>Angola</name>
                    <styleUrl>#NoneIconStyle</styleUrl>
                    <Point>
                        <coordinates>17.5379654426636,-12.2994772211426,0</coordinates>
                    </Point>
                </Placemark>
            ... ignore these

            <Folder>
                <name>A -</name>
                <Placemark>
                    <name>Afghanistan</name>
                    <Polygon>
                        <outerBoundaryIs>
                            <LinearRing>
                                <coordinates>
65.62729644775391,37.33319854736328,0 65.64692687988283,37.45888137817383,0 65.70137023925781,37.53693008422852,0 65.76608276367188,37.53416061401367,0 65.7855224609375,37.56887817382813,0 66.30274963378906,37.32360076904297,0 66.53876495361328,37.36051177978516,0 66.58690643310547,37.36803817749023,0 66.66525268554688,37.33832168579102,0 66.74442291259766,37.36137008666992,0 67.02163696289063,37.37720108032227,0 67.20025634765625,37.24665069580078,0 67.22942352294922,37.19192886352539,0 67.26637268066406,37.18526077270508,0 67.42440795898438,37.23498916625977,0 67.52163696289063,37.27248001098633,0 67.55745697021484,37.21554183959961,0 67.64940643310547,37.24608993530273,0 67.77413940429689,37.20608901977539,0 67.77715301513672,37.18579864501953,0 

每个国家都有。我想为每个国家/地区制作单独的文件。我想忽略最初的'lables'文件夹,并在树中将坐标向上移动一个文件夹。那么阿富汗.KML就是

<?xml version="1.0" encoding="UTF-8"?>
<kml>
    <Document>
        <Folder>
            <name>Countries</name>
                <Placemark>
                    <name>Afghanistan</name>
                    <Polygon>
                        <outerBoundaryIs>
                            <LinearRing>
                                <coordinates>
65.62729644775391,37.33319854736328,0 65.64692687988283,37.45888137817383,0 65.70137023925781,37.53693008422852,0 65.76608276367188,37.53416061401367,0 65.7855224609375,37.56887817382813,0 66.30274963378906,37.32360076904297,0 66.53876495361328,37.36051177978516,0 66.58690643310547,37.36803817749023,0 66.66525268554688,37.33832168579102,0 66.74442291259766,37.36137008666992,0 67.02163696289063,37.37720108032227,0 67.20025634765625,37.24665069580078,0 67.22942352294922,37.19192886352539,0 67.26637268066406,37.18526077270508,0 67.42440795898438,37.23498916625977,0 67.52163696289063,37.27248001098633,0 67.55745697021484,37.21554183959961,0 67.64940643310547,37.24608993530273,0 67.77413940429689,37.20608901977539,0 67.77715301513672,37.18579864501953,0 
    ...etc

我的XSLT几乎可以工作

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" version="1.0" omit-xml-declaration="yes"/>
    <xsl:template match="/">
        <xsl:apply-templates select="*[local-name()='kml']/*[local-name()='Document']"/>
    </xsl:template>
    <xsl:template match="*[local-name()='kml']/*[local-name()='Document']">
        <Document>
            <xsl:apply-templates select="*[local-name()='Folder']"/>
        </Document>
    </xsl:template>
    <xsl:template match="*[local-name()='Folder']">
        <xsl:apply-templates select="*[local-name()='Folder' or local-name()='Placemark']"/>
    </xsl:template>
    <xsl:template match="*[local-name()='Placemark']">
        <name>{name}</name> <!-- !! -->
        <xsl:result-document method="xml" href="d:\downloads\countries\{name}.xml">-->
        <xsl:apply-templates select="*[local-name()='Polygon']"/>
        </xsl:result-document>
    </xsl:template>
    <xsl:template match="*[local-name()='Polygon']">
        <Polygon>
            <xsl:apply-templates select="*[local-name()='outerBoundaryIs']"/>
        </Polygon>
    </xsl:template>
    <xsl:template match="*[local-name()='outerBoundaryIs']">
        <outerBoundaryIs>
            <xsl:apply-templates select="*[local-name()='LinearRing']"/>
        </outerBoundaryIs>
    </xsl:template>
    <xsl:template match="*[local-name()='LinearRing']">
        <LinearRing>
                </LinearRing>
        <xsl:apply-templates select="*[local-name()='coordinates']"/>
    </xsl:template>
    <xsl:template match="*[local-name()='coordinates']">
        <coordinates>
            <xsl:value-of select="."/>
        </coordinates>
    </xsl:template>
</xsl:stylesheet>

但我无法让处理器识别'名称'并切换文件(标有<!-- !! -->)。

是否有可以帮助我的XSL向导?

谢谢!

3 个答案:

答案 0 :(得分:3)

  

我无法让处理器识别“名称”并切换文件(标有<!-- !! -->)。

  <name>{name}</name> <!-- !! -->
  <xsl:result-document method="xml" href="d:\downloads\countries\{name}.xml">

我认为你应该更好地写下这样的事情:

        <name><xsl:value-of select="name"/></name>
        <xsl:variable name="filename"
          select="concat('d:\downloads\countries\',name,'.xml')" />
        <xsl:result-document method="xml" href="{$filename}">

这最终会更具可读性(在其他答案(+1)的同一行):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xpath-default-namespace="http://www.opengis.net/kml/2.2"
    version="2.0">
    <xsl:output indent="yes"/>

    <xsl:template match="/*/*/*/*[matches(name,'[A-Z]\s+-')]/Placemark">
        <xsl:result-document href="d:\downloads\countries\{name}.xml">
            <kml>
                <Document>
                    <Folder>
                        <name>Countries</name>
                        <xsl:copy-of select="."/>
                    </Folder>  
                </Document>
            </kml>
        </xsl:result-document>
    </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:3)

这为您提供样本输入所需的输出;

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs"
  version="2.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/kml">
    <xsl:apply-templates select="Document/Folder[name/text()='Countries']/Folder[name/text()='Labels']/Folder[matches(name/text(),'[A-Z] -')]"/>
  </xsl:template>

  <xsl:template match="Folder">
    <xsl:variable name="country" select="Placemark/name/text()"/>
    <xsl:result-document href="{$country}.xml">
      <kml>
        <Document>
          <Folder>
            <name>Countries</name>
            <xsl:copy-of select="Placemark"/>
          </Folder>  
        </Document>
      </kml>
    </xsl:result-document>
  </xsl:template>

</xsl:stylesheet>

它做了几个假设......

  1. 文档结构如您所示,其中国家/地区实际位于Labels文件夹中。
  2. 国家/地区文件夹将包含在与给定正则表达式匹配的字母数字文件夹中

答案 2 :(得分:2)

以下样式表适用于http://www.calvert.ch/download/world-borders.kml数据(注意xpath-default-namespace)。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xpath-default-namespace="http://www.opengis.net/kml/2.2"
        version="2.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <xsl:apply-templates select="//Folder[matches(name,'[A-Z] -')]"/>
  </xsl:template>

  <xsl:template match="Folder">
    <xsl:for-each select="Placemark">
      <xsl:result-document href="{name}.xml">
      <kml>
        <Document>
          <Folder>
            <name>Countries</name>
            <xsl:copy-of select="."/>
          </Folder>  
        </Document>
      </kml>
    </xsl:result-document>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>