2014-02-13 134 views
1

我有一些XML如下...動態命名空間匹配和添加元素使用XSLT

<ns1:service1 xmlns:ns1="http://foo.com/service_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<ns1:SystemInfo> 
    <ns1:functionMode>Y</ns1:functionMode> 
</ns1:SystemInfo> 
</ns1:service> 

現在我需要把它做兩件事情

  1. 裹在SOAP信封
  2. 在系統的系統信息中插入一個跨標籤

以下作品包裝...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:param name = "transId" /> 

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

    <xsl:template match="*"> 
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
     <soapenv:Header/> 
     <soapenv:Body> 
     <xsl:copy-of select="/*"/> 
     </soapenv:Body> 
    </soapenv:Envelope> 
    </xsl:template> 

</xsl:stylesheet> 

現在我需要添加標籤,問題是我們不知道名稱空間是什麼(它可以根據請求更改)。所以我不能硬編碼它。但是,它已經在根標籤中。

所以之後我想...

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Header/> 
    <soapenv:Body> 
    <ns1:service1 xmlns:ns1="http://foo.com/service_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <ns1:SystemInfo> 
     <ns1:trans /> 
    <ns1:functionMode>Y</ns1:functionMode> 
    </ns1:SystemInfo> 
    </ns1:service> 
    </soapenv:Body> 
</soapenv:Envelope> 

但是,這似乎並沒有完成它....

<xsl:template match="*[local-name()='SystemInfo']"> 
    <xsl:copy> 
    <xsl:element name="type"/> 
    <xsl:call-template name="copy-children"/> 
    </xsl:copy> 
</xsl:template> 

<!-- Copy the children of the current node. --> 
<xsl:template name="copy-children"> 
    <xsl:copy-of select="./*"/> 
</xsl:template> 

應該採取什麼上面是不是?

+0

你爲什麼發明了'複製children'而不是'的',並讓身份模板處理跟他們? – keshlam

+0

你的身份模板和你的'match =「*」'模板之間也有衝突。我認爲後者的意圖是「匹配=」/「' - 即匹配根節點以在整個文檔中應用包裝。 – keshlam

+0

...什麼是非命名空間的元素?這似乎是你打算構建'ns1:trans'的地方...... – keshlam

回答

3

相反,如果使用XSL:複製的將剛纔複製的當前元素,而不允許你做任何改動,使用XSL:申請模板

<soapenv:Body> 
    <xsl:apply-templates select="@*|node()"/> 
    </soapenv:Body> 

然後,你可以寫一個模板以匹配您的SystemInfo元素,並添加您需要的任何新元素。你甚至可以使用namespace-uri函數將它添加到相同的名稱空間。

<xsl:template match="*[local-name()='SystemInfo']"> 
    <xsl:copy> 
    <xsl:element name="trans" namespace="{namespace-uri()}" /> 
    <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

試試這個XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:param name="transId"/> 

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

    <xsl:template match="/"> 
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
     <soapenv:Header/> 
     <soapenv:Body> 
     <xsl:apply-templates select="@*|node()"/> 
     </soapenv:Body> 
    </soapenv:Envelope> 
    </xsl:template> 

    <xsl:template match="*[local-name()='SystemInfo']"> 
    <xsl:copy> 
     <xsl:element name="trans" namespace="{namespace-uri()}" /> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 
+0

很好的答案!我會確認,然後給支票! – Jackie