2013-04-23 106 views
0

我是xslt的新手。我試圖將XML從一個模式轉換爲另一個模式。我想在轉換後「擺脫」舊的命名空間。如果我需要它進行轉換,我如何在轉換後擦除舊的模式。本質上,我想http://positionskillmanagementservice.webservices.com消失,完全由http://newschema(我重新命名節點後)替換。我能夠通過從Dimitre Novatchev的方法來執行大部分的我想要的東西:change the namespace of an element with xslt用xslt擺脫舊的命名空間

這是XML:

<ns:positionSkillResponse xmlns:ns="http://positionskillmanagementservice.webservices.com"> 
<ns:return>1</ns:return> 
<ns:return>9</ns:return> 
</ns:positionSkillResponse> 

這是XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ns="http://positionskillmanagementservice.webservices.com" 
    version="1.0"> 

    <xsl:output method="xml" /> 

    <xsl:template match="ns:return"> 
    <parameter> 
     <xsl:apply-templates select="@*|node()"/> 
    </parameter> 
    </xsl:template> 

    <xsl:template match="ns:position"> 
    <parameter> 
     <xsl:apply-templates select="@*|node()"/> 
    </parameter> 
    </xsl:template> 

    <xsl:template match="ns:positionSkillResponse"> 
    <positionSkillRequest > 
     <xsl:apply-templates select="@*|node()"/> 
    </positionSkillRequest > 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template>  

    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

我檢查工作與this tool

回答

1

你的嘗試過於具體。試試這個更普遍的一種:

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:ns_old="http://positionskillmanagementservice.webservices.com" 
>  
    <xsl:output method="xml" /> 

    <!-- matches any node not handled elsewhere --> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template>  

    <!-- matches elements in the old namespace, re-creates them in the new --> 
    <xsl:template match="ns_old:*"> 
     <xsl:element name="ns:{local-name()}" namespace="http://newschema"> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:element> 
    </xsl:template> 

    <!-- if you don't have namespaced attributes you won't need this template --> 
    <xsl:template match="@ns_old:*"> 
     <xsl:attribute name="ns:{local-name()}" namespace="http://newschema"> 
      <xsl:value-of select="."/> 
     </xsl:attribute> 
    </xsl:template> 
</xsl:stylesheet> 

它提供:

<ns:positionSkillResponse xmlns:ns="http://newschema"> 
    <ns:return>1</ns:return> 
    <ns:return>9</ns:return> 
</ns:positionSkillResponse> 

  • 你並不需要在XSLT申報xmlns:ns="http://newschema"因爲你實際上並沒有從節點輸入文檔中的該命名空間。
  • 這也意味着你可以聲明舊的命名空間爲xmlns:ns="http://positionskillmanagementservice.webservices.com"並使用它像<xsl:template match="ns:*">。這與XSL處理器完全相同,但如果使用不同的前綴(如ns_old),則可能不會讓人類讀者感到困惑。
  • 您可以任意選擇您的輸出前綴(<xsl:element name="ns:{local-name()}" ...)。這與XSLT中聲明的名稱空間無關。不使用前綴都將導致具有默認命名空間的文件中:

    <positionSkillResponse xmlns="http://newschema"> 
        <return>1</return> 
        <return>9</return> 
    </positionSkillResponse> 
    
2

託默勒格向您展示了一個更好的方式來寫你的轉型,但並沒有真正回答你的問題直接。在樣式表中使用文字結果元素(例如<a>...</a>)時,它們會與樣式表中該元素的範圍內的所有名稱空間一起復制到輸出中,但有一些例外。其中一個例外是,如果名稱空間在exclude-result-prefixes元素中列出,則該名稱空間將被忽略,該元素通常與命名空間聲明一起放置在xsl:stylesheet元素中。因此,如果您不像Tomalak所建議的那樣重構樣式表,可以通過在xsl:stylesheet元素中添加exclude-result-prefixes =「ns」來刪除名稱空間。