2015-08-13 28 views
1

我有一個要求,即必須將SOAP消息插入到消息字段長度爲200個字符的DB中。 我必須使用XSLT來實現這一點,並且我正在獲取CDATA部分中的SoapMessage。使用XSL將CDATA中的XML溢出爲多個塊

下面是我在一個變量存儲CDATA標籤

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v4="http://www.example.com/ServiceBody/V4"> 
    <soapenv:Header> 
    </soapenv:Header> 
    <soapenv:Body> 
    <v4:getBookDetails> 
     <v4:Request> 
     <catalog> 
      <book id="bk101"> 
      <author>Gambardella, Matthew</author> 
      <title>XML Developer's Guide</title> 
      <genre>Computer</genre> 
      <price>44.95</price> 
      <publish_date>2000-10-01</publish_date> 
      <description>An in-depth look at creating applications with XML.</description> 
      </book> 
     </catalog> 
     </v4:Request> 
    </v4:getBookDetails> 
    </soapenv:Body> 
</soapenv:Envelope> 

下面內的SOAP消息是,我已經寫得到的消息到多個標籤,這樣我可以將其插入到DB的XSLT 。

<xsl:stylesheet extension-element-prefixes="date str" exclude-result-prefixes="dp str date" version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://exslt.org/dates-and-times" xmlns:str="http://exslt.org/strings"> 
    <xsl:output method="xml"/> 
    <xsl:template match="/"> 
     <xsl:variable name="cdataVariable"> 
      <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text> 
      <xsl:copy-of select="."/> 
      <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text> 
     </xsl:variable> 
     <MessageInChunks> 
      <stringLength><xsl:value-of select="string-length($cdataVariable)"/></stringLength> 
      <xsl:choose> 
       <xsl:when test="string-length($cdataVariable) &lt; 200"> 
        <Chunks> 
         <xsl:copy-of select="$cdataVariable"/> 
        </Chunks>   
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:call-template name="splitMessageIntoChunks"> 
         <xsl:with-param name="messageToSplit"> 
         <xsl:copy-of select="$cdataVariable"/> 
         </xsl:with-param> 
        </xsl:call-template> 
       </xsl:otherwise> 
      </xsl:choose> 
     </MessageInChunks> 
    </xsl:template> 

    <xsl:template name="splitMessageIntoChunks"> 
     <xsl:param name="messageToSplit"/> 
     <xsl:variable name="chunkSize" select="'200'"/> 
     <xsl:if test="string-length($messageToSplit) >0"> 
      <Chunks> 
       <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text> 
       <xsl:copy-of select="substring($messageToSplit, 12, $chunkSize)"/> 
       <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text> 
      </Chunks> 
      <xsl:call-template name="splitMessageIntoChunks"> 
       <xsl:with-param name="messageToSplit" select="substring($messageToSplit, $chunkSize+1)"/> 
      </xsl:call-template> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

但是,我越來越犯規輸出包含的元素的值預期爲字符串函數的輸出不顯示的元素。

我需要這樣的東西。

<MessageInChunks> 
<Chunks>&lt;![CDATA[<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v4="http://www.example.com/ServiceBody/V4"> 
    <soapenv:Header> 
    </soapenv:Header> 
    <soapenv:Body> 
    <v4:getBookDet]]&gt;</Chunks> 
<Chunks>&lt;![CDATA[ails> 
     <v4:Request> 
     <catalog> 
      <book id="bk101"> 
      <author>Gambardella, Matthew</author> 
      <title>XML Developer's Guide</title> 
      <genre>Compu]]&gt; 
</Chunks> 
<Chunks>&lt;![CDATA[ter</genre> 
      <price>44.95</price> 
      <publish_date>2000-10-01</publish_date> 
      <description>An in-depth look at creating applications with XML.</description> 
     ]]&gt; 
</Chunks> 
<Chunks>&lt;![CDATA[ </book> 
     </catalog> 
     </v4:Request> 
    </v4:getBookDetails> 
    </soapenv:Body> 
</soapenv:Envelope>]]&gt; 
</Chunks> 
</MessageInChunks> 

基本上我需要的是一個灑XML消息到200個字符塊,使用XSLT把它變成一個CDATA部分。

請幫我解決這個問題。

+0

既然你到了數據分割成200個字符右塊的邏輯,這基本上是http://stackoverflow.com/questions/6696382/xslt-how的副本-to-轉換的XML節點到字符串。 –

+0

@ AndreasVeithen ..將輸入XML轉換爲字符串在我的場景中無效,因爲在將消息顯示在另一個工具中之前,必須將此消息重新轉換爲XML。由於我使用Data Power,因此我使用dp:serialize,如其中一個答案中的建議,它對我很有用。 –

回答

0

我看你有標記ibm-datapower你的問題。您是否在DataPower設備上運行此XSLT?如果是這樣,你真的應該看看DataPower擴展元素dp:serialize,這會讓你的生活更輕鬆。

到這裏看看:http://www-01.ibm.com/support/knowledgecenter/SS9H2Y_6.0.1/com.ibm.dp.xi.doc/serialize_element.html

+0

謝謝bjimba .. dp:序列化在這種情況下工作。我不得不刪除CDATA部分,只是序列化SOAP消息,瞧......一切正常...... :) –

+0

很高興聽到它。你能接受這個答案嗎,所以其他人會知道嗎? – bjimba

0

我認爲,首先,您必須擺脫XML標籤才能將所有內容視爲字符串並將其拆分。

我建議做這樣的事情:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml"/> 
    <xsl:template match="*"> <!-- GET rid of XML tags by replacing them with escaped chars --> 
     &lt;<xsl:value-of select="name()"/><xsl:for-each select="@*"><xsl:text> </xsl:text><xsl:value-of select="name()"/>="<xsl:value-of select="."/>"</xsl:for-each>&gt;<xsl:apply-templates/>&lt;/<xsl:value-of select="name()"/>&gt; 
    </xsl:template> 

    <xsl:template match="/"> 
     <xsl:variable name="everything_in_one_string"><xsl:apply-templates/></xsl:variable> <!-- Put complete output in one variable --> 

     <xsl:variable name="everything_in_one_string_normalized" as="xs:string" select="normalize-space($everything_in_one_string)"/> <!-- Get rid of whitespace --> 

     <xsl:variable name="string_length_of_total" as="xs:integer" select="string-length($everything_in_one_string_normalized)"/> 

     <xsl:variable name="max_string_length_of_substrings" as="xs:integer" select="200"/> 

     <xsl:variable name="runs_necessary" as="xs:integer" select="ceiling($string_length_of_total div $max_string_length_of_substrings) cast as xs:integer"/> 
                     <!-- Compute how many chunks of 200 chars we need. --> 

     <MessageInChunks> 
     <xsl:for-each select="1 to $runs_necessary"> 
      <xsl:variable name="current_run" as="xs:integer" select="."/> 
      <Chunks><xsl:value-of select="substring($everything_in_one_string_normalized,((($current_run - 1)* $max_string_length_of_substrings) + 1),200)"/></Chunks> 
      <!-- Always extract 200 chars from the string. 
      For the first run: Start at 1: ((1 - 1) * 200) + 1 = 0 * 200 + 1 = 1 
      Second run: ((2 - 1) * 200) + 1 = 1 * 200 + 1 = 201 
      and so on 
      --> 
     </xsl:for-each> 
     </MessageInChunks> 

    </xsl:template> 

</xsl:stylesheet> 
+0

該解決方案並不完全正確,因爲它沒有序列化名稱空間聲明並且字符引用未正確轉義。如果OP需要一個僅用於記錄目的的解決方案,那可能是好的,但如果需要稍後能夠重新構建SOAP消息,則不會。 –

+0

@cis。我不能夠使用它,因爲我需要在另一個監視工具上重現SOAP消息,並且我不能篡改消息。 –