Разделите KML на подфайлы с помощью XSLT, почти там, но не можете заставить его работать - PullRequest
2 голосов
/ 27 июля 2011

У меня есть файл 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 ]

3 голосов
/ 27 июля 2011

Это дает желаемый результат на входе сэмпла;

<?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. Папки стран будут содержаться в папках с алфавитными буквами, которые соответствуют заданному регулярному выражению
3 голосов
/ 27 июля 2011

Я не могу заставить процессор распознавать «имя» и переключать файлы (помеченные <!-- !! -->).

  <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>
2 голосов
/ 28 июля 2011

Следующая таблица стилей работает с данными 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>
...