2014-06-30 41 views
1

如何在不事先知道將由發件人任意使用的命名空間前綴的情況下,替換XML消息的一個或多個元素的命名空間uri?如何使用xslt替換命名空間uri

我知道這個問題的形式已經被問過很多次了,但是我發現的每一個答案(這裏和其他網站)都假定了一個前綴的確切知識。根據定義,前綴是任意的,對此的解決方案不應要求加強對所用前綴的瞭解。

我有一個解決方案,但它導致垃圾我不需要在輸出中。簡單的輸入:

<?xml version="1.0" encoding="UTF-8"?> 
<myThing xmlns:s="http://tempuri3.org/"> 
    <s:thisThing> 
     <thatThing xmlns="http://cheapCookies.org/"/> 
     <anotherThing xmlns="http://kingkong.org"> 
      <thisThing/> 
     </anotherThing> 
    </s:thisThing> 
</myThing> 

這是XSLT:

<?xml version="1.0" ?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:param name="sourceNamespace" select="'http://tempuri3.org/'" /> 
    <xsl:param name="targetNamespace" select="'http://tempuri.org'"/> 

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

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

    <xsl:template match="*"> 
     <xsl:choose> 
      <xsl:when test="namespace-uri() = $sourceNamespace"> 
       <xsl:element name="{name()}" namespace="{$targetNamespace}"> 
        <xsl:apply-templates select="node() | @*"/> 
       </xsl:element> 
      </xsl:when> 

      <xsl:otherwise> 
       <xsl:call-template name="identity"/> 
      </xsl:otherwise> 
     </xsl:choose> 

    </xsl:template> 
</xsl:stylesheet> 

這是上面XSLT的輸出:

<?xml version="1.0" encoding="utf-8"?> 
<myThing xmlns:s="http://tempuri3.org/"> 
    <s:thisThing xmlns:s="http://tempuri.org"> 
     <thatThing xmlns="http://cheapCookies.org/" xmlns:s="http://tempuri3.org/"/> 
     <anotherThing xmlns="http://kingkong.org" xmlns:s="http://tempuri3.org/"> 
      <thisThing/> 
     </anotherThing> 
    </s:thisThing> 
</myThing> 

這是所需的輸出:

<?xml version="1.0" encoding="utf-8"?> 
<myThing xmlns:s="http://tempuri.org/"> 
    <s:thisThing> 
     <thatThing xmlns="http://cheapCookies.org/"/> 
     <anotherThing xmlns="http://kingkong.org"> 
      <thisThing/> 
     </anotherThing> 
    </s:thisThing> 
</myThing> 
+0

「*根據定義,前綴是任意的,*」前綴是任意的,名稱空間不是。從描述中不清楚您是否事先知道源代碼中使用的名稱空間。 –

+0

我知道源和目標命名空間uris,但我不知道前綴。 – JMorgan

回答

2

I知道的源和目標空間URI,

那麼你或許應該這樣做:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:old="http://tempuri3.org/" 
exclude-result-prefixes="old"> 

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="old:*"> 
    <xsl:element name="{local-name()}" namespace="http://tempuri.org"> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:element> 
</xsl:template> 

</xsl:stylesheet> 

結果可能略有根據所使用的確切處理器有所不同。例如,Saxon 6.5將返回:

<?xml version="1.0" encoding="UTF-8"?> 
<myThing xmlns:s="http://tempuri3.org/"> 
    <thisThing xmlns="http://tempuri.org"> 
    <thatThing xmlns="http://cheapCookies.org/"/> 
    <anotherThing xmlns="http://kingkong.org"> 
     <thisThing/> 
    </anotherThing> 
    </thisThing> 
</myThing> 
+0

非常好! local-name()....它並沒有立即發生,我不需要輸出上的前綴。 – JMorgan