# What Is CDATA? — XML CDATA Sections, the ]]> Problem, and Why Test Reports Use Them

Canonical: https://commareports.com/glossary/cdata
Published: 2026-11-03

> A CDATA section tells an XML parser to treat its contents as plain text, so < and & need no escaping. The syntax, the one sequence it cannot contain, how to split it, and why JUnit XML puts stack traces and logs in CDATA.

# CDATA

**A CDATA section is a part of an XML document that the parser reads as
plain text, not markup.** It starts with `<![CDATA[` and ends with
`]]>`. Inside it, `<` and `&` mean themselves.

```xml
<system-out><![CDATA[
GET /api/users?id=7&expand=team  200
expected <div class="row"> but got <span>
]]></system-out>
```

Without CDATA the same element needs every `<` written as `&lt;` and
every `&` as `&amp;`. After parsing, both forms produce exactly the same
text. CDATA is a convenience for whoever writes the file and whoever
reads it raw, not a different kind of data.

## The one rule: `]]>` ends it

CDATA has no escape character. The first `]]>` closes the section, so
text that contains that sequence has to be split across two sections:

```xml
<![CDATA[if (a[b[0]]]]><![CDATA[> 1) fail()]]>
```

The first section ends after `]]`, the second starts with `>`, and the
parser joins them back into `if (a[b[0]]> 1) fail()`. Every serialiser
that writes CDATA should do this. Ones that don't produce files that
break the moment a log line happens to contain `]]>`, which minified
JavaScript and some array-indexing code do.

## What CDATA cannot fix

CDATA changes how markup characters are read. It does not make illegal
characters legal. XML 1.0 forbids most control characters (U+0000 to
U+001F, except tab, newline and carriage return) **anywhere**, CDATA
included. ANSI colour codes start with U+001B, so a test runner that
copies coloured terminal output into its XML report produces a file that
strict parsers reject outright:

```
not well-formed (invalid token): line 214, column 31
```

The fix belongs in the writer: strip ANSI sequences (or disable colour
with `NO_COLOR=1` / `--no-color` in CI) before the output is stored.

## Where you meet it

- **[JUnit XML](/glossary/junit-xml).** `<system-out>`, `<system-err>`
  and the bodies of `<failure>` and `<error>` are usually CDATA, because
  stack traces and assertion diffs are full of angle brackets.
- **RSS and Atom feeds.** Item descriptions often carry HTML inside
  CDATA so the feed stays well-formed.
- **SVG and XHTML.** Inline `<style>` and `<script>` in an SVG file are
  wrapped in CDATA so CSS selectors like `a > b` and `&&` in code don't
  need escaping.
- **Config and build files.** Maven POMs, Android resources and
  Jenkins job XML use it for embedded scripts.

## CDATA in HTML

Plain HTML has no CDATA sections. The HTML parser treats `<![CDATA[`
as a bogus comment, except inside inline `<svg>` and `<math>`, where
it is recognised. The `//<![CDATA[ … //]]>` wrapper still seen in old
`<script>` tags exists only so one page could be valid as both HTML
and XHTML. In a page served as `text/html` it does nothing and can be
deleted.

## Reading a JUnit file full of CDATA

Raw JUnit XML with long CDATA logs is hard to scan: the failure you
want is buried between thousands of lines of captured output. Paste the
file into the free [JUnit XML viewer](/tools/junit-xml-viewer) to get
the failures first, with each test's output folded under it, then share
the page as a link with the people who need to look at the failure.

### Related

- [JUnit XML](/glossary/junit-xml) — the format with no specification
- [Byte order mark](/glossary/byte-order-mark) — another invisible
  character that breaks parsers
- [Mojibake](/glossary/mojibake) — when the bytes are fine and the
  encoding is wrong
- [XML to JSON converter](/tools/xml-to-json) ·
  [JUnit XML viewer](/tools/junit-xml-viewer)
- [ReportPortal alternatives](/alternatives/reportportal-alternatives)
- [Glossary](/glossary)
