从KML到XSLT的KML xmlns属性冲突

从KML到XSLT的KML xmlns属性冲突,xslt,kml,google-earth,gml,opengis,Xslt,Kml,Google Earth,Gml,Opengis,我有一个XSLT,负责将KML重新格式化为GML <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.opengis.net/gml" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:gx="http://w

我有一个XSLT,负责将KML重新格式化为GML

<?xml version="1.0"  encoding="utf-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.opengis.net/gml" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" exclude-result-prefixes="kml">

    <xsl:output method="xml" indent="yes" encoding="utf-8" omit-xml-declaration="yes" />

   <!-- Removes all nodes with any empty text -->
  <xsl:template match="*[.='']"/>

  <!-- Removes all nodes with any empty attribute -->
  <xsl:template match="*[@*='']"/>

    <xsl:template match="text()"/>

    <xsl:template match="/">

      <MultiSurface>
        <surfaceMembers>
          <xsl:apply-templates />
        </surfaceMembers>
      </MultiSurface>
    </xsl:template>

    <xsl:template match="kml:Placemark">
          <xsl:apply-templates />      
    </xsl:template>

    <xsl:template match="kml:Point">
        <!--<Point>
            <xsl:apply-templates />
        </Point>-->
    </xsl:template>

    <xsl:template match="kml:LineString">
        <!--<LineString>
            <xsl:apply-templates />
        </LineString>-->
    </xsl:template>

    <xsl:template match="kml:Polygon">
          <Polygon>
              <xsl:apply-templates />
          </Polygon>
    </xsl:template>

    <xsl:template match="kml:outerBoundaryIs">
        <exterior>
            <xsl:apply-templates />
        </exterior>
    </xsl:template>

    <xsl:template match="kml:innerBoundaryIs">
        <interior>
            <xsl:apply-templates />
        </interior>
    </xsl:template>

    <xsl:template match="kml:LinearRing">
        <LinearRing>
            <xsl:apply-templates />
        </LinearRing>
    </xsl:template>

    <xsl:template match="kml:coordinates">
        <posList>
        <!--<xsl:value-of select="translate(., ',', ' ')" />-->
        <xsl:call-template name="output-tokens">
          <xsl:with-param name="list" select="." />
        </xsl:call-template>
        </posList>
    </xsl:template>

    <xsl:template name="output-tokens">
        <xsl:param name="list" />
        <xsl:variable name="newlist" select="concat(normalize-space($list), ' ')" />
        <xsl:variable name="first" select="substring-before($newlist, ' ')" />
        <xsl:variable name="remaining" select="substring-after($newlist, ' ')" />
<!-- long, lat, alt-->
        <xsl:variable name="long" select="substring-before($first, ',')" />

        <xsl:choose>
            <xsl:when test="contains(substring-after($first, ','), ',')">
                <xsl:variable name="lat" select="substring-before(substring-after($first, ','), ',')" />
                <xsl:value-of select="concat($lat, ' ', $long, ' ')" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:variable name="lat" select="substring-after($first, ',')" />
                <xsl:value-of select="concat($lat, ' ', $long, ' ')" />
            </xsl:otherwise>
        </xsl:choose>

        <xsl:if test="$remaining">
            <xsl:call-template name="output-tokens">
                <xsl:with-param name="list" select="$remaining" />
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

我觉得答案将是愚蠢的简单,但我还没有偶然发现它,我已经没有东西可以尝试和谷歌。你们有什么建议

理解XML名称空间前缀本身并没有意义是很重要的。它们只是名称空间名称的简写形式,名称空间是标识名称空间的URI。名称空间名称(通过名称空间声明属性绑定到前缀)实际上标识了具有名称空间意识的XML处理器(如XSLT处理器)中的名称空间和作用域名称。因此,尝试将一个前缀绑定到两个可选名称空间名称是没有意义的

所有这些都与XML模式文档的位置无关。但是,假设您正在谈论的KML2.2是由位于的模式文档描述的,其名称空间名称是
http://www.opengis.net/kml/2.2
,其模式明确规定。实例文档不能随意使用不同的名称空间名称(尽管它们可以随意将任何名称空间前缀绑定到该名称——它不必是“kml”)

一句话:只有两种可能性:

  • 由于使用了错误的命名空间名称,客户端提供的文档格式不正确。在这种情况下,最好的做法是修复客户机文件中的名称空间名称,或者要求客户机这样做。您可以通过编辑它来实现这一点,也可以编写样式表来执行这种转换。无论哪种方式,根据您希望文档符合的模式验证生成的文档都是一个好主意

  • 客户机提供的文档的XML文档类型(松散意义)与您预期的不同,并且已准备好处理。在这种情况下,唯一要做的就是从客户端请求一个正确类型的新文件


  • 重要的是要理解XML名称空间前缀本身并没有意义。它们只是名称空间名称的简写形式,名称空间是标识名称空间的URI。名称空间名称(通过名称空间声明属性绑定到前缀)实际上标识了具有名称空间意识的XML处理器(如XSLT处理器)中的名称空间和作用域名称。因此,尝试将一个前缀绑定到两个可选名称空间名称是没有意义的

    所有这些都与XML模式文档的位置无关。但是,假设您正在谈论的KML2.2是由位于的模式文档描述的,其名称空间名称是
    http://www.opengis.net/kml/2.2
    ,其模式明确规定。实例文档不能随意使用不同的名称空间名称(尽管它们可以随意将任何名称空间前缀绑定到该名称——它不必是“kml”)

    一句话:只有两种可能性:

  • 由于使用了错误的命名空间名称,客户端提供的文档格式不正确。在这种情况下,最好的做法是修复客户机文件中的名称空间名称,或者要求客户机这样做。您可以通过编辑它来实现这一点,也可以编写样式表来执行这种转换。无论哪种方式,根据您希望文档符合的模式验证生成的文档都是一个好主意

  • 客户机提供的文档的XML文档类型(松散意义)与您预期的不同,并且已准备好处理。在这种情况下,唯一要做的就是从客户端请求一个正确类型的新文件

  • Google的名称空间是KML标准的扩展:参见

    因此,如果您只是更改样式表以处理不同的名称空间,它可能会工作,也可能不会工作,这取决于(a)是否实际使用了Google扩展,以及(b)编写样式表以处理扩展的可靠性(丢弃任何具有空文本或空属性的元素的模板规则看起来并不是一个特别好的开始。)

    一般来说,我的建议是,当您有两个使用不同名称空间的XML词汇表变体时,首先将一个变体预处理为另一个变体。在这种情况下,这是否是正确的策略取决于更详细地了解情况的细节

    您不应该尝试编写一个样式表来处理这两个变体,结果是到处都是条件逻辑,使代码混乱,调试成为一场噩梦

    但是我已经看到了一种成功使用的替代方法:不是预处理源文档来处理变体词汇表,而是预处理样式表。

    Google的名称空间是KML标准的扩展:参见

    因此,如果您只是更改样式表以处理不同的名称空间,它可能会工作,也可能不会工作,这取决于(a)是否实际使用了Google扩展,以及(b)编写样式表以处理扩展的可靠性(丢弃任何具有空文本或空属性的元素的模板规则看起来并不是一个特别好的开始。)

    一般来说,我的建议是,当您有两个使用不同名称空间的XML词汇表变体时,首先将一个变体预处理为另一个变体。在这种情况下,这是否是正确的策略取决于更详细地了解情况的细节

    您不应该尝试编写一个样式表来处理这两个变体,结果是到处都是条件逻辑,使代码混乱,调试成为一场噩梦

    但是我看到了一种成功使用的替代方法:不是预处理源文档来处理变体词汇表,而是预处理样式表。

    您确定
    <kml xmlns="http://www.opengis.net/kml/2.2">
    
    <kml xmlns="http://earth.google.com/kml/2.2">...</kml>
    
    xmlns:kml="http://www.opengis.net/kml/2.2 http://earth.google.com/kml/2.2"