I need to embed arbitrary (syntactically valid) XML documents within a wrapper XML document. The embedded documents are to be regarded as mere text, they do not need to be p
Isn't that what character entities are for?
Consider using XInclude instead of trying to embed an XML document inside another. The XInclude parse="text" attribute will force the XML to be treated as text, not markup.
When you escape the ending angular bracket of the inner CDATA, most XML parsers will not complain about the well-formedness of your XML. Using this "workaround", you should be able to nest multiple CDATA sections.
Something like:
<?xml version="1.0"?>
<SomeData>
<![CDATA[
<SomeMoreData>
<![CDATA[
yeah, this trick rocks! ...
]]>
</SomeMoreData>
]]>
</SomeData>
Note that the inner CDATA has its ending ">" escaped as >
.
You need to properly escape the text. You don't say what language you're using, but generally: you build a DOM, create a Text node that contains your "inner" XML, and then serialize that DOM. The serializer will handle escaping for you.
The key point here is use a serializer to produce your output. Don't simply write strings, because you're all but guaranteed to produce something that's not well-formed XML.
You can do this by simply adding the document (without its <?xml
declaration) as a child tom some parent. SOAP is doing this - it has a <Body>
element that can contain whatever xml message one wants to send.
SOAP defines the XSD this way:
<xs:element name="Body" type="tns:Body" />
<xs:complexType name="Body">
<xs:sequence>
<xs:any namespace="##any" minOccurs="0"
maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##any" processContents="lax">
</xs:anyAttribute>
</xs:complexType>
One easy solution is that you can have adjacent CDATA sections. <![CDATA[A]]><![CDATA[B]]>
is the same as <![CDATA[AB]]>
. Hence, you can have <![CDATA[]]]]><![CDATA[>]]>
, a ]]>
close tag split over two CDATA
sections.