Data Formats

CDATA in XML: Syntax, Escaping and Examples

A CDATA section lets an XML element contain text with literal < and & characters. The parser treats that content as text instead of element markup.

Published

CDATA syntax inside an XML element

The element's text is x < 10 & ready. The delimiters are XML syntax and are not part of that text. A CDATA section does not create a child element, declare an encoding or turn its contents into executable code.

<message><![CDATA[x < 10 & ready]]></message>

CDATA and escaped text can represent the same value

Both elements contain the string <b>Hello</b> & ready. In cdata, the apparent b tags are text. In escaped, the parser resolves the entity references to the same characters. Choose the representation that keeps your XML readable; consumers usually care about the resulting value.

<samples>
  <cdata><![CDATA[<b>Hello</b> & ready]]></cdata>
  <escaped>&lt;b&gt;Hello&lt;/b&gt; &amp; ready</escaped>
</samples>

Entity references inside CDATA stay literal

literal contains the five characters &amp;, while resolved contains one ampersand. Escaping a value first and then wrapping it in CDATA changes the resulting text. The interactive comparison below includes both cases so you can inspect the actual output.

<literal><![CDATA[&amp;]]></literal>
<resolved>&amp;</resolved>

How to include ]]> without nesting sections

This uses two adjacent sections. The first ends after the two literal closing brackets; the second begins with >. Their combined text is a ]]> b. Another option is ordinary escaped text: <message>a ]]&gt; b</message>.

CDATA sections cannot nest. When generating XML, use an XML serializer and its text-node facilities instead of concatenating arbitrary user input between delimiters. A DOM createCDATASection call rejects a value containing ]]>.

<message><![CDATA[a ]]]]><![CDATA[> b]]></message>

CDATA vs PCDATA, attributes and comments

In a DTD, an attribute declared with type CDATA is a different use of the term. It does not permit <![CDATA[...]]> inside an attribute value. Use normal attribute escaping there.

FormMeaningCommon mistake
CDATA sectionElement text with literal markup charactersExpecting &amp; to become & inside the section
PCDATA / ordinary parsed textCharacter data where entity references are recognizedLeaving a literal & unescaped
Attribute valueA quoted value inside a start tagTrying to put a CDATA section in the value
XML commentComment syntax, separate from element textUsing CDATA to comment out data

What happens when CDATA is converted to JSON?

The converter's Smart mapping represents parsed character data as JSON strings. CDATA boundaries and the original choice of entity spelling are not preserved in this mapping. Compare the values, not a byte-for-byte reconstruction of the XML.

The example includes Привет and नमस्ते. These are ordinary Unicode text inside CDATA. If the original file bytes were decoded incorrectly, adding a CDATA wrapper cannot repair the encoding.

CDATA is not an HTML safety mechanism

A string containing <b>Hello</b> remains data while the XML parser reads CDATA. If an application later inserts that string as HTML, the browser applies HTML rules. Render it as text, or apply the application's HTML sanitization policy when HTML is actually intended.

CDATA syntax belongs to XML. Do not use it as a general escaping method for ordinary HTML documents. The examples here display the resulting strings as text.

Frequently asked questions

Can CDATA contain another CDATA section?

No. The first ]]> closes the current section. Split the text into adjacent sections or let an XML serializer escape it as ordinary text.

Does CDATA allow any binary data?

No. The content still has to contain characters permitted by the XML version. For arbitrary bytes, use a representation such as Base64 when the consuming format expects it.

Is CDATA required for HTML stored inside XML?

No. Correctly escaped element text can represent the same HTML string. CDATA is a convenient source notation, not a guarantee that the stored HTML is safe to render.

Try the example

Compare CDATA, escaping and literal entities

Convert one document containing three representations of text.

<samples><cdata><![CDATA[<b>Привет / नमस्ते</b> & ready]]></cdata><escaped>&lt;b&gt;Привет / नमस्ते&lt;/b&gt; &amp; ready</escaped><literal><![CDATA[&amp;]]></literal></samples>

Expected result: cdata and escaped have identical text; literal contains the five-character string &amp;.

Try the example

Join text across two CDATA sections

The ]]> characters are split across adjacent sections.

<message><![CDATA[a ]]]]><![CDATA[> b]]></message>

Expected result: The message value is a ]]> b. The CDATA delimiters are absent from the parsed text.

Inspect the parsed text

See what CDATA becomes in JSON

Load the comparison example and check the resulting strings in the local XML to JSON converter.

Open XML to JSON Converter →

Documentation and standards