Skip to content

Una sezione CDATA (acronimo di Character Data) è un costrutto definito dalla specifica W3C XML 1.0 §2.7 che permette di includere in un documento XML blocchi di testo contenenti caratteri riservati (<, >, &) senza che il parser li interpreti come markup. È un artefatto di sintassi, non di semantica: il contenuto di una sezione CDATA e il testo equivalente espresso con entity reference producono lo stesso XML Information Set, cioè lo stesso albero logico per il parser.

Cosa significa CDATA (Character Data)

CDATA sta per Character Data: dati carattere. In una sezione CDATA il parser XML interpreta ogni sequenza come testo letterale, senza riconoscere markup, entity reference o processing instruction. L’unica sequenza che ha significato speciale è la chiusura ]]>, che non può mai apparire all’interno della sezione.

È importante distinguere due piani:

  • Piano sintattico: CDATA è una scorciatoia di scrittura che evita di dover scrivere &lt; al posto di < e &amp; al posto di &.
  • Piano semantico: il contenuto di una sezione CDATA è indistinguibile dal testo equivalente con entity reference. Dopo il parsing le due forme sono equivalenti e un’applicazione che legge l’XML tramite DOM o SAX non può nemmeno sapere se il dato originale era in CDATA o no (tranne con API specifiche come LexicalHandler in Java).

Sintassi di una sezione CDATA

La sintassi è rigida e case-sensitive. Apertura con <![CDATA[ e chiusura con ]]>:

<![CDATA[
testo libero con caratteri < > & senza escape
]]>

Esempio completo dentro un documento XML ben formato:

<?xml version="1.0" encoding="UTF-8"?>
<script>
  <![CDATA[
    if (a < b && c > d) {
      return "a minore di b e c maggiore di d";
    }
  ]]>
</script>

Senza CDATA lo stesso contenuto richiederebbe l’escape esplicito di tre caratteri:

<script>
  if (a &lt; b &amp;&amp; c &gt; d) {
    return "a minore di b e c maggiore di d";
  }
</script>

Le due forme sono equivalenti per il parser, ma la prima è più leggibile quando il payload contiene molti caratteri riservati (codice, HTML, espressioni regolari).

PCDATA vs CDATA: come i parser le distinguono

La distinzione tra PCDATA e CDATA è una delle più confuse nella letteratura XML, perché il termine CDATA appare in due contesti diversi:

  • PCDATA (Parsed Character Data) — il testo normale di un elemento, che viene analizzato dal parser: entity reference come &amp; vengono risolte, tag vengono riconosciuti. È la modalità di default per il contenuto di ogni elemento.
  • CDATA section (<![CDATA[ ... ]]>) — un blocco in cui il parser sospende l’interpretazione e tratta tutto come testo letterale.
  • CDATA attribute type — nelle DTD, CDATA è anche il tipo più generico che un attributo può assumere (es. <!ATTLIST img src CDATA #REQUIRED>). Non va confuso con le sezioni CDATA: qui significa semplicemente “stringa di caratteri”.

Quando si cerca su Google “cdata dtd” o “cdata element” si sta quasi sempre parlando del tipo di attributo definito in DTD, non delle sezioni. Sono due concetti disgiunti che condividono il nome per ragioni storiche della specifica SGML da cui XML deriva.

Quando usare CDATA: casi d’uso concreti

Le sezioni CDATA risolvono un problema molto specifico: inserire grandi blocchi di testo contenenti caratteri riservati XML senza inquinare la leggibilità con decine di entity reference. I casi d’uso dove conviene davvero usarle sono pochi ma ricorrenti.

Feed RSS e Atom con HTML nel description

Il caso d’uso più comune in ambito SEO. I feed RSS 2.0 usano CDATA nell’elemento <description> per veicolare HTML senza doverlo escapare:

<item>
  <title>Guida all'analisi dei log server</title>
  <link>https://www.evemilano.com/blog/analisi-log/</link>
  <description><![CDATA[
    <p>In questo articolo analizziamo <strong>pattern di crawling</strong>
    di Googlebot usando <a href="https://www.python.org/">Python</a>.</p>
  ]]></description>
</item>

Il feed Atom (RFC 4287) ha invece una soluzione più pulita: l’attributo type="html" o type="xhtml" sull’elemento <content>. Molti generatori di feed usano comunque CDATA anche in Atom per compatibilità con i reader che applicano euristiche di parsing.

SOAP envelope, WSDL e file di configurazione

Nei web service SOAP è frequente trovare CDATA quando il body di un messaggio contiene payload eterogenei: XML serializzato, JSON, query SQL, espressioni XPath. Allo stesso modo i file di configurazione di molti tool (Log4j, Ant, Maven plugin) usano CDATA per i pattern di log o gli script inline:

<PatternLayout>
  <Pattern><![CDATA[%d{ISO8601} [%t] %-5p %c & %m%n]]></Pattern>
</PatternLayout>

XSLT, MathML e snippet di codice

Gli stylesheet XSLT usano CDATA per includere JavaScript o codice destinato all’output senza escape manuale. Stesso discorso per documenti tecnici che contengono esempi di codice: una sezione CDATA evita di dover escapare ogni minore/maggiore.

Regole e limitazioni di una sezione CDATA

Le regole imposte dalla specifica XML 1.0 sono quattro e sono tutte verificate dal parser in fase di validazione:

  1. Non sono annidabili. Non è possibile scrivere <![CDATA[ ... <![CDATA[ ... ]]> ... ]]>: la prima occorrenza di ]]> chiude la sezione.
  2. La sequenza ]]> non può apparire nel contenuto. Per inserirla letteralmente va spezzata in due sezioni contigue oppure sostituendo > con &gt;.
  3. Le entity reference non vengono risolte. All’interno di CDATA, &amp; è la stringa letterale di cinque caratteri, non la e commerciale.
  4. Possono apparire solo nel content di un elemento, mai negli attributi, nel prolog o nei commenti.

Una limitazione meno nota: una sezione CDATA non è un nodo di tipo Element nel DOM, ma un nodo di tipo CDATASection (che eredita da Text). Molte API di alto livello lo espongono come semplice testo, perdendo l’informazione sulla forma originale.

CDATA nelle sitemap XML: serve davvero?

La domanda arriva spesso durante gli audit tecnici: “la mia sitemap.xml contiene CDATA, devo rimuoverlo?”. La risposta breve è no, non cambia nulla, ma vale la pena spiegare perché.

Il protocollo sitemaps.org definisce sette campi (loc, lastmod, changefreq, priority, alternate, image, video), tutti con contenuto semplice. Alcuni plugin avvolgono il valore di loc in CDATA per cautela, tipicamente per gestire URL con caratteri speciali non correttamente URL-encoded. Esempio:

<url>
  <loc><![CDATA[https://www.esempio.com/prodotto?id=42&ref=home]]></loc>
  <lastmod>2026-04-22</lastmod>
</url>

Googlebot e Bingbot processano entrambe le forme in modo identico. Non esiste alcun impatto SEO (positivo o negativo) dovuto alla presenza di CDATA in una sitemap. L’unica vera best practice è assicurarsi che gli URL siano URL-encoded secondo RFC 3986: a quel punto il CDATA diventa superfluo.

CDATA vs entity reference: quale scegliere

La scelta è puramente una questione di leggibilità e di tooling:

  • Pochi caratteri da escapare (1-3 occorrenze) → entity reference. Mantiene il documento omogeneo e riduce la superficie di errori di chiusura.
  • Blocco di testo lungo con molti caratteri riservati (HTML nel feed, snippet di codice, query SQL) → CDATA. Migliora drasticamente la leggibilità.
  • Contenuto generato da template engine → quasi sempre entity reference, perché il template esegue automaticamente l’escape del testo in output.
  • Contenuto binario → nessuna delle due. Il binario va base64-encoded, non inserito in CDATA.

Un’altra considerazione pratica: alcuni parser XML meno rigorosi o XSLT processor trattano i contenuti CDATA in modo leggermente diverso quando si applica xsl:value-of disable-output-escaping. In pipeline di trasformazione complesse è utile saperlo.

CDATA in HTML5: perché non si usa più

Nell’HTML serializzato (text/html) le sezioni CDATA non esistono. Il parser HTML5 ignora la sintassi <![CDATA[ ... ]]> e la trasforma in un commento bogus. Questo è un cambio rispetto a XHTML, dove il CDATA era legale perché XHTML è XML.

L’HTML5 Living Standard definisce due contesti in cui il parser HTML si comporta come se fosse una sezione CDATA, ma senza la sintassi esplicita:

  • Contenuto di <script> e <style> — il parser non interpreta il markup al loro interno.
  • Contenuto di elementi MathML e SVG inline — qui la sintassi <![CDATA[ ... ]]> è consentita perché questi subset sono parsati in foreign content mode, che rispetta le regole XML.

In pratica: su una pagina HTML5 standard, mettere <![CDATA[ dentro uno <script> è un retaggio XHTML che oggi non serve più. La pagina continua a funzionare, ma quei sette caratteri finiscono nell’output come commento ignorato.

Commenti XML vs sezione CDATA

Commenti e sezioni CDATA sono spesso confusi perché entrambi “sospendono” qualcosa, ma hanno scopi opposti:

  • Commento XML (<!-- ... -->): il parser ignora il contenuto. Non finisce nel DOM come dato, è visibile solo con API lessicali. Serve per annotare il sorgente.
  • Sezione CDATA (<![CDATA[ ... ]]>): il parser include il contenuto come testo, ma senza interpretarlo come markup. Serve per veicolare dati.

Un commento XML non può contenere la sequenza -- al suo interno, esattamente come una sezione CDATA non può contenere ]]>. Entrambe le limitazioni esistono per garantire che il parser possa sempre riconoscere il terminatore senza ambiguità.

Errori comuni e troubleshooting del parser

Gli errori di parsing legati a CDATA sono ricorrenti e quasi sempre riconducibili a pochi pattern. Riporto quelli che emergono più di frequente durante audit di feed e sitemap:

  • Chiusura prematura: il contenuto contiene la sequenza ]]>. Errore tipico quando si inserisce codice XML generato da un altro processo senza sanitizzare.
  • Case sensitivity: <![cdata[ ... ]]> in minuscolo non è valido. La parola chiave CDATA deve essere sempre in maiuscolo.
  • Spazi nell’apertura: <! [CDATA[ con spazio tra <! e [CDATA[ produce errore di parsing.
  • Encoding mismatch: se il documento dichiara UTF-8 ma il contenuto CDATA contiene byte non validi UTF-8 (tipico con database legacy in Latin-1), il parser fallisce con not well-formed.
  • BOM invisibile: un Byte Order Mark all’interno del CDATA viene preservato come carattere testuale e può rompere il consumer downstream.

Per validare una sezione CDATA in Python basta xml.etree.ElementTree o lxml: se il parser non solleva eccezioni, la sezione è ben formata. Un esempio di parsing con logging degli errori:

from lxml import etree

parser = etree.XMLParser(strip_cdata=False, recover=False)
try:
    tree = etree.parse("feed.xml", parser)
    root = tree.getroot()
    for item in root.iter("item"):
        desc = item.findtext("description")
        print(desc[:80])
except etree.XMLSyntaxError as e:
    print(f"XML non ben formato: {e}")

Il flag strip_cdata=False è essenziale se si vuole preservare la forma originale del documento; con il default True, lxml fonde automaticamente CDATA e testo normale.

FAQ su CDATA in XML

Cosa significa esattamente ]]>?

È la sequenza di chiusura obbligatoria di una sezione CDATA. Tre caratteri: due parentesi quadre chiuse seguite dal simbolo maggiore. Non esiste modo di “escapare” questa sequenza dentro la sezione stessa: se serve, va spezzata in due sezioni CDATA contigue.

Si possono annidare due sezioni CDATA?

No. La prima ]]> chiude sempre la sezione, indipendentemente dalla struttura attesa. Se serve includere codice che a sua volta contiene <![CDATA[, va inserito letteralmente perché dentro CDATA non viene riconosciuto come markup.

CDATA e JSON: esiste un equivalente?

No. JSON non ha caratteri riservati strutturali a parte " e \, che si escapano con backslash. Il problema che CDATA risolve non esiste in JSON.

CDATA impatta la SEO del feed RSS o della sitemap?

No. Googlebot processa in modo identico il contenuto CDATA e il contenuto con entity reference. L’impatto è esclusivamente sulla leggibilità e sulla manutenibilità del sorgente XML.

Autore

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Ultimi articoli aggiornati

16 min lettura

Metodologia operativa per la diagnosi di problemi su web server Linux tramite l'analisi dei log di sistema e applicativi. Il testo dettaglia l'ispezione di /var/log, l'interrogazione dei demoni con journalctl per monitorare lo stack LEMP e la configurazione di logrotate.
0 mi piace
21 min lettura

I crawler di Meta e Amazon generano milioni di richieste senza back-off: come quantificarli nei log, verificarne l'autenticità e fermarli con cache, robots.txt, rate limiting e WAF, senza perdere i link preview.
1 mi piace
22 min lettura

Difendere WordPress dai commenti spam con una strategia defense in depth a tre layer: configurazioni applicative, regole edge su Cloudflare, barriere a livello web server. Honeypot PHP, regole .htaccess e Nginx modernizzate, Cloudflare Turnstile, fail2ban. Snippet completi pronti da incollare.
0 mi piace
22 min lettura

Analisi tecnica della persistenza dei dati nel protocollo HTTP tramite header Set-Cookie. Comprendere la meccanica dei cookie, attributi come Max-Age e i limiti di Googlebot come crawler stateless è essenziale per diagnosticare problemi di rendering e involuntary cloaking.
4 mi piace
19 min lettura

Analisi dell'architettura RAG nativa per WordPress sviluppata interamente in PHP e MySQL, senza dipendenze da database vettoriali esterni. Il sistema supera i limiti della ricerca lessicale integrando la ricerca semantica su VPS o hosting condivisi con meno di 1GB di RAM.
3 mi piace

Richiedi un preventivo SEO e Google Ads

Porta il tuo sito web al livello successivo con l’esperienza di EVE Milano. La nostra agenzia di Search Marketing ha ricevuto oltre

User Access Addon Required

This shortcode requires the CF7 Database User Access addon to display data.

Please purchase and install the User Access addon to enable this feature.

Purchase User Access Addon

richieste di preventivo, un segnale chiaro della fiducia che imprenditori e manager, come te, ripongono nella nostra specializzazione tecnica e verticale nella SEO e PPC. Se la tua organizzazione cerca competenze specifiche per emergere nei risultati di Google, noi siamo pronti a fornire quel valore aggiunto. Richiedi un preventivo ora e scopri la differenza tra noi e gli altri.
Richiedi un preventivo

Vuoi ricevere un avviso al mese con le nuove guide pubblicate?

Iscriviti alla newsletter!