This tip might save you a few minutes.
A colleague recently wanted his BPEL process (Oracle SOA Suite) to return a string containing XML markup, and within that markup he needed to include a CDATA section. The requirement for returning this document as a string will perhaps be discussed in another article.
Short answer: it's not possible.
Longer answer:
Those of you who have some experience with [Oracle] BPEL Process development will have probably come across the { http://schemas.oracle.com/xpath/extension}getContentAsString()function. Those of you who don't: this function enables you to treat an XML structure like a string. It's the only way (that my colleague and I know of) to do this in Oracle BPEL.
What happens when have some XML structure with a CDATA section, pass it to getContentAsString and assign it to an xsd:string ? The start and end angled brackets ("<" and ">") pertaining to the CDATA delimiters alone are replaced by their entity references ("<" and ">"). All other markup in the XML structure would be left intact. Why?
If you only witness this happening via the console audit trails, or basically through any XML parser, you are unlikely to realize that the getContentAsString function actually embeds the XML structure in a CDATA element already!
What you would see via the online console:
<root>
<ElementList>
<element1>data1</element1>
<element2>data2</element2>
<element3><![CDATA[ some CDATA characters ]]></element3>
</ElementList>
</root>
Where the element root is of type xsd:string and is the node to which you're assigning the output of getContentAsString.
But if you look at the raw message, that is, without parsing the XML data (eg.: soapUI) then you see this:
<root><![CDATA[
<ElementList>
<element1>data1</element1>
<element2>data2</element2>
<element3><![CDATA[ some CDATA characters ]]></element3>
</ElementList>]]>
</root>
The XML spec clearly states that CDATA sections cannot be nested. Hence the escaping of those angle brackets. What's more, CDATA sections are not meant to be parsed (that is the point of having CDATA sections), and that includes those escaped characters. Don't go thinking that the XML parser will see them and convert them back to angle brackets.
So what can you do?
Don't convert your structure to a string. Return a complex type. If you do so, then you can do something similar to the following in a transformation for example:
<element3>
<xsl:text><![CDATA[<![CDATA[ some CDATA characters ]]]]><![CDATA[>]]></xsl:text>
</element3>
By putting that right angle bracket in a separate CDATA section, I avoid "closing" the first CDATA section marked in red so that I can also include those two square brackets "]" in it. The output would be something like this:
<root>
<ElementList>
<element1>data1</element1>
<element2>data2</element2>
<element3><![CDATA[ some CDATA characters ]]></element3>
</ElementList>
</root>
However, this time the element rootis not of type xsd:string; instead, root is now a complex type defined as the parent element of ElementList, itself a complex type having element1, element2 and element3 as child nodes.
Hope it helps.