Archive for the ‘CDATA’ Category

Just pressing this quick blog for people who always ask question about CDATA handling in request/response using soapUI/Groovy.

Now the very first question anybody would ask is why we use CDATA in XML? Isn’t the XML suppose to be the simplest form of data communication? If yes, then why by introducing the CDATA tag in XML we are making it more complex?

Well, my take on above question would be as follow :

Yes, XML is still remains simplest form of data communication. And actually by introducing the CDATA tag in request/response we are making the life more simpler in certain cases. Now you might wonder what are those cases?

Consider the case when, you want to transfer some data which is in XML tag format (but not necessarily pure xml). Now if you will directly transfer the XML file across the machine the receiving XML parser will parse that complete xml. That would obviously take some  time to process & few more work. This can be avoided if we directly pass the required XML as “String”. Yes and CDATA actually help in achieving the same. So whenever you want to pass the XML tags in XML you can use CDATA and then those XML tags will be treated as String.

Now coming back the “CDATA Handling” in soapui using Groovy. This can be further divided into 2 parts :

CDATA in response :

if( submit.response == null )
   return
def responseContent = submit.response.responseContent
responseContent = responseContent.replaceAll( "<!\\[CDATA\\[", "" )
responseContent = responseContent.replaceAll( "]]>", "" )
log.info( responseContent )
submit.response.responseContent =  responseContent

Above mentioned code should be written in following navigation :
Select the Project name & double click to open a new window, select the “Events” tab and add a SubmitListener.afterSubmit handler. Set its content to above groovy code lines.

CDATA in request : *

if( request.requestContent == null )
   return
log.info "Old request with CDATA : " + request.requestContent
def requestContent = request.requestContent
requestContent = requestContent.replaceAll( "<!\\[CDATA\\[", "" )
requestContent = requestContent.replaceAll( "]]>", "" )
log.info "New request without CDATA : " + request.requestContent
request.requestContent =  requestContent

* please make sure that playing with request CDATA is not hampering your server response. As in if your server is expected to receive the CDATA in request.

Above mentioned code should be written in following navigation :
Select the Project name & double click to open a new window, select the “Events” tab and add a RequestFilter.filterRequest handler. Set its content to above groovy code lines.

There are few other ways to do it and soapui Documentation provides more details about the same at soapUI
Source code courtesy : soapUI.org

UPDATE :: Below is the another way to handle CDATA in soaui using property transfer. Thanks to “Tim Reynolds” for sharing it many other users 🙂
Also, do have a look into the comments of this blog, you might find another interesting finding by Tim.

<!-- A TestResponse, lets call it TestStepNameXYZ -->
<soap:Envelope
    xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
    xmlns:rpc="http://www.w3.org/2003/05/soap-rpc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
   <SomeCmdResponse xmlns="http://wsdl.coolstuff.com/Morestuff/">
      <SomeCmdResult xmlns="">
          <![CDATA[<RESULT><THE_ELEMENT_I_WANT/><LotsOfXmlElements/></RESULT>]]>
      </SomeCmdResult>
  </SomeResponse>
</soap:Body>
</soap:Envelope>

<!-- A Transfer TestStep with multiple Transfers -->
<!-- Call this XFR-GetToCDATA -->
<!-- Here you define/declare the required namespaces -->
<!-- Next you use XPATH to get to the element that contains the CDATA -->
<!-- note the use of text(), this gets you ALL the CDATA -->
<!-- AND does the translation for you - very nice -->
<!-- Use  Source: TestStepNameXYZ Property: Response -->
declare namespace ns1='';
declare namespace coolstuff='http://wsdl.coolstuff.com/Morestuff/';
declare namespace rpc='http://www.w3.org/2003/05/soap-rpc';
declare namespace soap='http://www.w3.org/2003/05/soap-envelope';
declare namespace saxon='http://saxon.sf.net/' ;
//coolstuff:SomeCmdResponse/SomeCmdResult/text()
<!-- Use  Target: TestCaseName/Project/global/youPickIt Property: SomeTmpPropName -->

<!-- Create a 2nd XFR Step -->
<!-- Call this XFR-UseTheUnCDATAdXml -->
<!-- XPATH to whatever you want, or you could just use the SomeTmpPropName in you groovy -->
<!-- Use  Source: TargetValueFromAbove Property: SomeTmpPropName -->
/RESULT/THE_ELEMENT_I_WANT
<!-- Use  Target: TestCaseName/Project/global/youPickIt Property: SomeOtherPropName -->