2015-10-21 39 views
4

我在下面有一個傳入的簡單xml請求,並且需要使用正確的名稱空間轉換到SOAP消息的下面。並且在傳入的XML請求中名稱空間不會如此,因此在形成SOAP消息時我們需要注意的名字空間也。有沒有任何XSLT代碼片段可以幫助我實現這一點。 注意 - 我們需要動態執行XSLT轉換,就像傳入請求可以是任何元素(如「GetImageRequest」)一樣,因此基於此元素需要構建名稱空間。 (也許我們可以把所有的名字空間中一個XML文件,並需要構造SOAP消息)動態XSLT轉換

傳入XML請求:

<request> 
<payload> 
<GetImageRequest> 
    <participantId>1191152220010</participantId> 
    <participantCode>131029</participantCode> 
    <groupCode>027198</groupCode> 
    <userType>EE</userType> 
    <clientName>Test</clientName> 
    <shoeboxID>123444</shoeboxID> 
    <imageID>45235</imageID> 
</GetImageRequest> 
</payload> 
</request> 

============== ==== 需要在適當的命名空間下構建SOAP消息。

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Header> 

    </soapenv:Header> 
    <soapenv:Body> 
     <get:GetShoeboxItemRequest xmlns:get="urn:webservice/server/mobile/shoebox/types/v1/GetShoeboxItem"> 
     <get:participantId>1060687620010</get:participantId> 
     <get:participantCode>1060687620010</get:participantCode> 
     <get:groupCode>027198</get:groupCode> 
     <get:userType>EE</get:userType> 
     <get:clientName>Test</get:clientName> 
     <get:shoeboxID>123444</get:shoeboxID> 
     </get:GetShoeboxItemRequest> 
    </soapenv:Body> 
</soapenv:Envelope> 

需要快速幫助。 XSLT代碼片段會很有幫助。

+2

「*基於此元素上需要構建名字空間* 「這還不夠清楚。請提供一個確切的規則來構建命名空間。我沒有看到'GetImageRequest'成爲'urn:webservice/server/mobile/shoebox/types/v1/GetShoeboxItem''的邏輯。 --- P.S.是[你的其他問題](http://stackoverflow.com/questions/33194911/xslt-transformation-from-soap)回答? –

回答

3

該轉化

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pRequestedItemName" select="'Shoebox'"/> 

<xsl:variable name="vUpper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/> 
<xsl:variable name="vLower" select="'abcdefghijklmnopqrstuvwxyz'"/> 

<xsl:variable name="vLcItemName" select= 
       "translate($pRequestedItemName, $vUpper, $vLower)"/> 

<xsl:variable name="vDynNamespace" select= 
    "concat('urn:webservice/server/mobile/', $vLcItemName, '/types/v1/Get', 'Item')"/> 

    <xsl:template match="/"> 
     <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
      <soapenv:Header> 
      </soapenv:Header> 
      <soapenv:Body> 
       <xsl:element name="get:Get{$pRequestedItemName}ItemRequest" 
        namespace="{$vDynNamespace}"> 
       <xsl:apply-templates select="/*/*/GetImageRequest/node()"/> 
       </xsl:element> 
      </soapenv:Body> 
     </soapenv:Envelope> 
    </xsl:template> 

    <xsl:template match="*"> 
    <xsl:element name="get:{name()}" namespace="{$vDynNamespace}"> 
     <xsl:copy-of select="namespace::*|@*"/> 
     <xsl:apply-templates/> 
    </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

當在提供源XML文檔施加:

<request> 
    <payload> 
     <GetImageRequest> 
      <participantId>1191152220010</participantId> 
      <participantCode>131029</participantCode> 
      <groupCode>027198</groupCode> 
      <userType>EE</userType> 
      <clientName>Test</clientName> 
      <shoeboxID>123444</shoeboxID> 
      <imageID>45235</imageID> 
     </GetImageRequest> 
    </payload> 
</request> 

產生想要的,正確的結果

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <get:GetShoeboxItemRequest 
     xmlns:get="urn:webservice/server/mobile/shoebox/types/v1/GetItem"> 
     <get:participantId>1191152220010</get:participantId> 
     <get:participantCode>131029</get:participantCode> 
     <get:groupCode>027198</get:groupCode> 
     <get:userType>EE</get:userType> 
     <get:clientName>Test</get:clientName> 
     <get:shoeboxID>123444</get:shoeboxID> 
     <get:imageID>45235</get:imageID> 
     </get:GetShoeboxItemRequest> 
    </soapenv:Body> 
</soapenv:Envelope> 

說明

  1. <xsl:element>指令的全功率使用。
  2. 使用AVTAttribute Value Templates
  3. 動態命名空間的唯一的變量部的應由變換的調用被提供爲a global parameter

如果您需要構建一個完全動態的命名空間(如轉換的調用者在全局參數傳遞),見this answer


UPDATE

的OP的評論澄清說,他可以在一個單獨的XML文檔或全局參數收集的所有請求特定的命名空間。

這裏是解決這個澄清問題

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pRequestData"> 
    <r name="GetImageRequest" 
    ns="urn:webservice/server/mobile/shoebox/types/v1/GetShoeboxItem"/> 
    <r name="SaveShoeBoxitemRequest" 
    ns="urn:webservice/server/mobile/shoebox/types/v1/SaveShoeboxItem"/> 
    <r name="SaveClaimWithReceiptRequest" 
    ns="urn:webservice/server/mobile/shoebox/types/v1/SaveClaimAndReceipt"/> 
    <r name="GetThumbNailImageRequest" 
    ns="urn:webservice/server/mobile/shoebox/types/v1/GetThumbnail"/> 
    <r name="AttachReceiptwithExistingClaimRequest" 
    ns="urn:webservice/server/mobile/shoebox/types/v1/AttachClaimAndReceipt"/> 
</xsl:param> 

<xsl:variable name="vParams" select="document('')/*/xsl:param[@name='pRequestData']"/> 

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

    <xsl:template match="*"> 
    <xsl:param name="pKey" select="local-name()"/> 
    <xsl:element name="get:{local-name()}" namespace="{$vParams/*[@name = $pKey]/@ns}"> 
     <xsl:copy-of select="namespace::*|@*"/> 
     <xsl:apply-templates> 
     <xsl:with-param name="pKey" select="$pKey"/> 
     </xsl:apply-templates> 
    </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

當在下面的XML文檔(所提供的一個具有​​的第二,不同名稱的孩子)施加這種轉變:

<request> 
    <payload> 
     <GetImageRequest> 
      <participantId>1191152220010</participantId> 
      <participantCode>131029</participantCode> 
      <groupCode>027198</groupCode> 
      <userType>EE</userType> 
      <clientName>Test</clientName> 
      <shoeboxID>123444</shoeboxID> 
      <imageID>45235</imageID> 
     </GetImageRequest> 
     <SaveShoeBoxitemRequest> 
      <participantId>1191152220010</participantId> 
      <participantCode>131029</participantCode> 
      <groupCode>027198</groupCode> 
      <userType>EE</userType> 
      <clientName>Test</clientName> 
      <shoeboxID>123444</shoeboxID> 
      <imageID>45235</imageID> 
     </SaveShoeBoxitemRequest> 
    </payload> 
</request> 

想要的,正確的(不同於其他答案中的「解決方案」)結果產生了

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
     <soapenv:Header/> 
     <soapenv:Body> 
      <get:GetImageRequest 
xmlns:get="urn:webservice/server/mobile/shoebox/types/v1/GetShoeboxItem"> 
      <get:participantId>1191152220010</get:participantId> 
      <get:participantCode>131029</get:participantCode> 
      <get:groupCode>027198</get:groupCode> 
      <get:userType>EE</get:userType> 
      <get:clientName>Test</get:clientName> 
      <get:shoeboxID>123444</get:shoeboxID> 
      <get:imageID>45235</get:imageID> 
      </get:GetImageRequest> 
      <get:SaveShoeBoxitemRequest 
xmlns:get="urn:webservice/server/mobile/shoebox/types/v1/SaveShoeboxItem"> 
      <get:participantId>1191152220010</get:participantId> 
      <get:participantCode>131029</get:participantCode> 
      <get:groupCode>027198</get:groupCode> 
      <get:userType>EE</get:userType> 
      <get:clientName>Test</get:clientName> 
      <get:shoeboxID>123444</get:shoeboxID> 
      <get:imageID>45235</get:imageID> 
      </get:SaveShoeBoxitemRequest> 
     </soapenv:Body> 
    </soapenv:Envelope> 
+0

嗨迪米特雷,感謝您的回覆。我需要XSLT是動態的,就好像任何一個釋放來自「Payload」標籤一樣,它應該相應地構建肥皂包。像這裏我們只爲「GetImageRequest」構建。我們如何在XSLT中做到這一點。需要你的幫助來做到這一點。 – user5458829

+0

@ user5458829,如果您指定規則如何從相應的子項「」構造頂級生成元素的名稱(例如「」),那麼這將是可能的,以及從源xml文檔中的相同對應元素構造命名空間字符串值。如果一個穩定的約定是不可能的,這些都可以作爲全局參數提供。 –

+0

嗨迪米特雷,感謝您的評論 – user5458829

0

所以,如果我知道的所有命名空間的5個元素我可以把一個 XML文件,並可以從XML文件中檢索。或者如你所說的可以在全局文件中定義那些名字空間 。

如果您有一個使用哪個名稱空間的映射以及哪個「root」元素名稱,您可以將它保留在樣式表本身中。

下面是一個例子(使用虛構的名稱空間,因爲你沒有指定自己):

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="http://www.example.com/my" 
exclude-result-prefixes="my"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<my:ns-map> 
    <ns root="GetImageRequest">urn:webservice/a/b/GetShoeboxItem</ns> 
    <ns root="SaveShoeBoxitemRequest">urn:webservice/c/d/SaveShoeBoxitemRequest</ns> 
    <ns root="SaveClaimWithReceiptRequest">urn:webservice/e/f/SaveClaimWithReceiptRequest</ns> 
    <ns root="GetThumbNailImageRequest">urn:webservice/g/h/GetThumbNailImageRequest</ns> 
    <ns root="AttachReceiptwithExistingClaimRequest">urn:webservice/i/k/AttachReceiptwithExistingClaimRequest</ns> 
</my:ns-map> 

<xsl:variable name="root" select="name(/request/payload/*)"/> 
<xsl:variable name="ns" select="document('')/xsl:stylesheet/my:ns-map/ns[@root=$root]"/> 

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

<xsl:template match="*" > 
    <xsl:element name="get:{local-name()}" namespace="{$ns}"> 
     <xsl:copy-of select="@*"/> 
     <xsl:apply-templates /> 
    </xsl:element> 
</xsl:template> 

</xsl:stylesheet>