使用 XSLT 将 KML 拆分为子文件,几乎已经完成,但无法使其工作

发布于 2024-11-26 20:46:25 字数 5482 浏览 2 评论 0原文

我有一个带有国家/地区边界的 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 

每个国家都有。我想为每个国家制作一个单独的文件。我想忽略最初的“标签”文件夹,并将具有坐标的文件夹在树中向上移动。所以阿富汗.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 向导可以帮助我吗?

谢谢!

I have a KML file with country borders

    <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 

It has every country. I want to make a separate files for each country. I want to ignore the initial 'lables' folder and move the Folder with the coordinates one up in the tree. So Afghanistan.KML would be

<?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

My XSLT nearly works

<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>

but I can't get the processor to recognise the 'name' and switch files (marked by <!-- !! -->).

Is there an XSL wizard whou could help me out?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

乄_柒ぐ汐 2024-12-03 20:46:25

这将为您提供示例输入所需的输出;

<?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. 国家/地区文件夹将包含在与给定正则表达式匹配的字母文件夹中

This gives you the desired output on your sample input;

<?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>

It makes a couple of assumptions...

  1. The document structure is as you have shown it, where the countries are actually within the Labels folder.
  2. Country folders will be contained within alphabet-letter folders that match the given regular expression
跨年 2024-12-03 20:46:25

我无法让处理器识别“名称”并切换文件(由 标记)。强>


  <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>

I can't get the processor to recognise the 'name' and switch files (marked by <!-- !! -->).

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

I think you should better write somthing like this:

        <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}">

This is finally what would be more readable (on the same line of the other answers (+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>
腹黑女流氓 2024-12-03 20:46:25

以下样式表适用于 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>

The following stylesheet works with the http://www.calvert.ch/download/world-borders.kml data (note 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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文