Search code examples
xmlxsltcdataibm-datapower

Spilt a XML in CDATA into multiple chunks using XSL


I have a requirement where I have to insert the SOAP Messages into a DB where the Message field character length is say 200 characters. I have to use XSLT to acheive this and I am getting the SoapMessage in a CDATA section.

Below is the SOAP Message that I store in a variable within a CDATA Tag

<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>

Below is the XSLT that I have written to get the message into multiple tags so that I can insert it into the DB.

<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>

But the output that I am getting doesnt contain the elements expect for the values as the output of the substring function is not displaying the elements.

I need something like this.

<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>

Basically what I need is to spilt a XML message into chunks of 200 characters and get it into a CDATA section using XSLT.

Kindly help me with this issue.


Solution

  • I see you have your question tagged with ibm-datapower. Are you running this XSLT on a DataPower appliance? If so, you really should look into the DataPower extension element dp:serialize, which will make your life much easier.

    Take a look here: http://www-01.ibm.com/support/knowledgecenter/SS9H2Y_6.0.1/com.ibm.dp.xi.doc/serialize_element.html