2017-03-07 44 views
0

我有一個XSLT,它具有將KML重新格式化爲GML的工作。將KML xmlns屬性從KML衝突到XSLT

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

通常我們的客戶給了我們,有一個KML打開標籤這樣的KML文件:

<kml xmlns="http://www.opengis.net/kml/2.2"> 

而且此實例的XSLT的偉大工程,以變換KML文件。 http://www.opengis.net/kml/2.2或可替代的XSLT文件的xmlns:KML是未設置爲:http://earth.google.com/kml/2.2但是我們一個今天已經......

<kml xmlns="http://earth.google.com/kml/2.2">...</kml> 

這不工作,我想這是因爲的KML xmlns屬性沒有被設置到了

我嘗試以下,但它沒有工作

xmlns:kml="http://www.opengis.net/kml/2.2 http://earth.google.com/kml/2.2" 

我覺得答案是愚蠢簡單,但我還沒有碰到過這還迷迷糊糊,我跑出來的東西,嘗試和谷歌。你們有什麼建議?

+0

你確定唯一的區別是命名空間嗎?如果是這樣,請考慮編寫第一個樣式表或樣式表步驟,將命名空間標準化爲您所期望的。 –

+0

請從處理器中顯示XSLT錯誤,因爲*這不起作用*是無用的。 – Parfait

回答

3

理解XML命名空間前綴不是固有意義是很重要的。它們僅僅是名稱空間名稱的縮寫形式,它是標識名稱空間的URI。它是名稱空間名稱,通過名稱空間聲明屬性綁定到前綴,該名稱空間實際上標識了名稱空間感知型XML處理器(如XSLT處理器)中的名稱空間和作用域名稱。因此,嘗試將一個前綴綁定到兩個替代名稱空間名稱是沒有意義的。

這與XML模式文檔的位置沒有任何關係。但是,假設您正在討論的KML 2.2是架構文檔http://schemas.opengis.net/kml/2.2.0/ogckml22.xsd中描述的那個,則其名稱空間名稱爲http://www.opengis.net/kml/2.2,如其架構明確指定的那樣。實例文檔無權使用不同的名稱空間名稱(儘管它們可以自由地綁定任何名稱空間前綴他們想要的名稱 - 它不必是「kml」)。

底線:只有兩種可能:

  1. 由客戶提供的文件格式不正確的使用了錯誤的命名空間名稱的結果。在這種情況下,最好的做法是在中修復客戶端文件中的名稱空間名稱,或者要求客戶端這樣做。你可以通過編輯來做到這一點,或者你可以編寫一個樣式表來執行這樣的轉換。無論哪種方式,根據您期望的符合的模式驗證生成的文檔可能是一個好主意。

  2. 客戶提供的文檔與您預期的不同,並且準備處理的XML文檔類型(鬆散意義)。在這種情況下,唯一要做的是從客戶端請求一個正確類型的新文件。

2

谷歌的命名空間是KML標準的延伸:看https://developers.google.com/kml/documentation/kmlreference

所以,如果你簡單地改變你的樣式表來處理不同的命名空間,它可能會或可能無法正常工作,這取決於(一) (b)樣式表是如何被強有力地寫入來處理擴展(放棄任何具有空文本或空屬性的元素的模板規則看起來不是特別好的開始。)

一般我的建議,當你有t使用不同名稱空間的XML詞彙表的變體是通過將一個變體預處理爲另一個變體來開始的。在這種情況下,這是否是正確的策略取決於更詳細地瞭解情況的細節。

你不應該做的是試圖編寫一個處理兩種變體的樣式表。你最終會遇到混亂你的代碼的條件邏輯,並使得調試成爲一場噩夢。

但我看到了一種成功使用的替代方法:代替預處理源文檔來處理變體詞彙表,而是預處理樣式表。