2013-04-07 103 views
1

我試圖構建一個Soap請求。所需的輸出是:如何從xslt輸出xml中刪除不需要的空xmlns

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
xmlns:soap1="http://acme.com/ws/soapheaders"> 
<soap:Header> 
    <soap1:locale>en</soap1:locale> 
    <soap1:authentication> 
     <soap1:username>john.doe</soap1:username> 
     <soap1:password>psw</soap1:password> 
    </soap1:authentication> 
</soap:Header> 

這裏是我的測試XSL(lanuage,用戶名和密碼在實際應用中傳遞):

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> 
<xsl:param name="language" select="'en'"/> 
<xsl:param name="username" select="'john.doe'"/> 
<xsl:param name="password" select="'psw'"/> 
<xsl:template match="/"> 
    <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
     xmlns:soap1="http://acme.com/ws/soapheaders" > 
     <xsl:call-template name="soapHeader"/>    
     <xsl:call-template name="soapBody"/> 
    </soap:Envelope> 
</xsl:template> 
<xsl:template name="soapHeader"> 
    <soap:Header> 
     <soap1:locale><xsl:value-of select="$language" /></soap1:locale> 
     <soap1:authentication> 
      <soap1:username><xsl:value-of select="$username" /></soap1:username> 
      <soap1:password><xsl:value-of select="$password" /></soap1:password> 
     </soap1:authentication> 
    </soap:Header> 
</xsl:template> 
<xsl:template name="soapBody"> 
</xsl:template> 
</xsl:stylesheet> 

但是,輸出是:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://acme.com/ws/soapheaders"> 
<soap:Header xmlns:soap=""> 
    <soap1:locale xmlns:soap1="">en</soap1:locale> 
    <soap1:authentication xmlns:soap1=""> 
     <soap1:username>john.doe</soap1:username> 
     <soap1:password>psw</soap1:password> 
    </soap1:authentication> 
</soap:Header> 

存在不需要的空名稱空間,如xmlns:soap =「」,xmlns:soap1 =「」。你能指點我正確的方向來消除這些不需要的文物嗎?

謝謝。

+0

User2254613,我強烈建議使用一種設計模式,使演示文稿與邏輯完全分離 - 又名「填充空白」技術。 – 2013-04-07 16:09:58

回答

0

我很驚訝你的XSLT處理器接受XSLT,因爲它不是有效的XML,而是使之有效的,並且也(我相信)解決您的問題,您應該<xsl:stylesheet>元素,而不是對上申報命名空間<soap:Envelope>元件:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
       xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
       xmlns:soap1="http://acme.com/ws/soapheaders"> 
+0

JLRishe,謝謝你的幫助。我用Altova XMLSpy測試了它,它並沒有抱怨xslt。將所有的namsespaces移動到你所建議的位置就行了!謝謝。 – user2254613 2013-04-07 15:23:15

-1

我強烈建議到呈現從邏輯分離。事實上,您可以進行獨立於任何可能演示文稿的轉換。

這裏談到的 「填充最坯」 技術(注意,這也解決了您不需要的命名空間的問題):

源XML文檔

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
xmlns:soap1="http://acme.com/ws/soapheaders" xmlns:gen="my:gen"> 
    <soap:Header> 
     <soap1:locale><gen:language/></soap1:locale> 
     <soap1:authentication> 
      <soap1:username><gen:username/></soap1:username> 
      <soap1:password><gen:password/></soap1:password> 
     </soap1:authentication> 
    </soap:Header> 
</soap:Envelope> 

Presentation-獨立轉化

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:gen="my:gen"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 
    <xsl:param name="language" select="'en'"/> 
    <xsl:param name="username" select="'john.doe'"/> 
    <xsl:param name="password" select="'psw'"/> 

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

<xsl:template match="gen:*"> 
    <xsl:value-of select= 
    "document('')/*/xsl:param[@name=local-name(current())]/@select"/> 
</xsl:template> 
</xsl:stylesheet> 

結果

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://acme.com/ws/soapheaders" xmlns:gen="my:gen"> 
    <soap:Header> 
     <soap1:locale>'en'</soap1:locale> 
     <soap1:authentication> 
     <soap1:username>'john.doe'</soap1:username> 
     <soap1:password>'psw'</soap1:password> 
     </soap1:authentication> 
    </soap:Header> 
</soap:Envelope> 

您可以現在有許多不同的呈現佈局的需要,並沒有任何變化相同的轉換(提供所有必需的參數已指定)產生任何格式

例如,如果你想生產這種新格式的結果:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://acme.com/ws/soapheaders"> 
    <soap:Header> 
     <soap1:personalized> 
     <soap1:locale> 
      <soap1:language>'en'</soap1:language> 
     </soap1:locale> 
     <soap1:authentication> 
      <soap1:username>'john.doe'</soap1:username> 
      <soap1:password>'psw'</soap1:password> 
     </soap1:authentication> 
     </soap1:personalized> 
    </soap:Header> 
</soap:Envelope> 

只適用於下面的XML文檔相同的轉換:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
xmlns:soap1="http://acme.com/ws/soapheaders" xmlns:gen="my:gen"> 
    <soap:Header> 
     <soap1:personalized> 
     <soap1:locale> 
      <soap1:language><gen:language/></soap1:language> 
    </soap1:locale> 
     <soap1:authentication> 
      <soap1:username><gen:username/></soap1:username> 
      <soap1:password><gen:password/></soap1:password> 
     </soap1:authentication> 
     </soap1:personalized> 
    </soap:Header> 
</soap:Envelope> 

進一步泛化可以通過提供佈局文檔的URL和參數文檔的url作爲變換的參數來實現。

+0

我不是那種低估了這一點的人,但是你的輸出在值的周圍有撇號,如果參數值是從外部傳入的(提問者說他​​最終會這樣做),這將不起作用。 – JLRishe 2013-04-07 19:11:33

+0

@JLRishe,當我指出我的答案結束時,這只是一個演示。這種技術的完整和普遍應用將接受佈局和參數作爲外部XML文檔URI。 – 2013-04-07 19:27:55

相關問題