Что означает <! [CDATA []]> в XML?

1014

Я часто нахожу этот странный CDATAтег в XMLфайлах:

<![CDATA[some stuff]]>

Я заметил, что этот CDATAтег всегда появляется в начале, а затем сопровождается некоторыми вещами.

Но иногда это используется, иногда это не так. Я предполагаю, что это означает, что some stuffэто «данные», которые будут вставлены после этого. Но что это за данные some stuff? Разве что-то, что я пишу в тегах XML, не является чем-то вроде данных?

dontWatchMyProfile
источник

Ответы:

951

CDATA означает Символьные данные, и это означает, что данные между этими строками включают в себя данные, которые могут быть интерпретированы как разметка XML, но не должны.

Основные различия между CDATA и комментариями:

  • Как указывает Ричард , CDATA по-прежнему является частью документа, а комментарий - нет.
  • В CDATA вы не можете включить строку ]]>( CDEnd), в то время как в комментарии --недопустимо .
  • Ссылки на параметры объекта не распознаются внутри комментариев.

Это означает, что эти четыре фрагмента XML из одного правильно сформированного документа:

<!ENTITY MyParamEntity "Has been expanded">

<!--
Within this comment I can use ]]>
and other reserved characters like <
&, ', and ", but %MyParamEntity; will not be expanded
(if I retrieve the text of this node it will contain
%MyParamEntity; and not "Has been expanded")
and I can't place two dashes next to each other.
-->

<![CDATA[
Within this Character Data block I can
use double dashes as much as I want (along with <, &, ', and ")
*and* %MyParamEntity; will be expanded to the text
"Has been expanded" ... however, I can't use
the CEND sequence. If I need to use CEND I must escape one of the
brackets or the greater-than sign using concatenated CDATA sections.
]]>

<description>An example of escaped CENDs</description>
<!-- This text contains a CEND ]]> -->
<!-- In this first case we put the ]] at the end of the first CDATA block
     and the > in the second CDATA block -->
<data><![CDATA[This text contains a CEND ]]]]><![CDATA[>]]></data>
<!-- In this second case we put a ] at the end of the first CDATA block
     and the ]> in the second CDATA block -->
<alternative><![CDATA[This text contains a CEND ]]]><![CDATA[]>]]></alternative>
Шон Виейра
источник
35
Как можно избежать символа последовательности CEND?
Томас Уэллер
23
У вас должно быть два раздела CDATA, чтобы объединить ]]и >- посмотрите этот ответ, чтобы узнать, как и почему.
Шон Виейра
2
должен ли быть символ новой строки между началом CDATA и необработанными данными?
Бен Сьюардс
2
Нет там не @BenSewards
Шон Виейра
5
Так этот кусок C-подобный код не может быть легко поместить в раздел CDATA: if (a[b[c]]>10) { }.
Андерс Торнблад
341

Раздел CDATA - это « раздел содержимого элемента, помеченный для синтаксического анализа как только символьные данные, а не разметка ».

Синтаксически, он ведет себя подобно комментарию:

<exampleOfAComment>
<!--
    Since this is a comment
    I can use all sorts of reserved characters
    like > < " and &
    or write things like
    <foo></bar>
    but my document is still well-formed!
-->
</exampleOfAComment>

... но это все еще часть документа:

<exampleOfACDATA>
<![CDATA[
    Since this is a CDATA section
    I can use all sorts of reserved characters
    like > < " and &
    or write things like
    <foo></bar>
    but my document is still well formed!
]]>
</exampleOfACDATA>

Попробуйте сохранить следующее в виде .xhtmlфайла ( не .html ) и открыть его с помощью FireFox ( не Internet Explorer ), чтобы увидеть разницу между комментарием и разделом CDATA; комментарий не будет отображаться при просмотре документа в браузере, а раздел CDATA:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" >
<head>
<title>CDATA Example</title>
</head>
<body>

<h2>Using a Comment</h2>
<div id="commentExample">
<!--
You won't see this in the document
and can use reserved characters like
< > & "
-->
</div>

<h2>Using a CDATA Section</h2>
<div id="cdataExample">
<![CDATA[
You will see this in the document
and can use reserved characters like
< > & "
]]>
</div>

</body>
</html>

В разделах CDATA следует обратить внимание на то, что они не имеют кодировки, поэтому нет возможности включить ]]>в них строку . Любые символьные данные, которые содержат ]]>, должны - насколько я знаю - вместо этого быть текстовым узлом. Аналогично, с точки зрения манипулирования DOM вы не можете создать раздел CDATA, который включает в себя ]]>:

var myEl = xmlDoc.getElementById("cdata-wrapper");
myEl.appendChild(xmlDoc.createCDATASection("This section cannot contain ]]>"));

Этот код манипулирования DOM будет либо генерировать исключение (в Firefox), либо приводить к плохо структурированному XML-документу: http://jsfiddle.net/9NNHA/

Ричард Дж.П. Ле Гуэн
источник
3
Тогда почему «ý» не разрешено в CDATA?
Бджан
11
@bjan - Что заставляет тебя думать, что это нелегальный персонаж? Похоже, у вас могут быть проблемы с кодировкой.
Ричард Дж.П. Ле Гуэн
Я открыл документ в IE, я также использую синтаксический анализатор MSXML, который объявил его как недопустимый символ. У меня есть xsd, в котором он объявлен как "type =" xs: string "". Это связано с кодировкой или версией XML?
Бджан
CDATA анализируется, и здесь также допускается только допустимый диапазон символов, он используется для экранирования блоков текста, содержащих символы, которые в противном случае были бы распознаны как разметка
bjan
1
Таким образом, мы могли бы использовать CDATA для контрабанды некоторого HTML в документ XML, чтобы HTML не перепутал структуру документа XML, а затем использовать XSLT, чтобы извлечь его и плюнуть в выводимый документ HTML.
Каз
69

Один большой пример использования: ваш xml включает программу в качестве данных (например, учебник по веб-страницам для Java). В этой ситуации ваши данные включают в себя большой набор символов, которые включают «&» и «<», но эти символы не должны быть XML.

Для сравнения:

<example-code>
while (x &lt; len &amp;&amp; !done) {
    print( &quot;Still working, &apos;zzz&apos;.&quot; );
    ++x;
    }
</example-code>

с

<example-code><![CDATA[
while (x < len && !done) {
    print( "Still working, 'zzzz'." );
    ++x;
    }
]]></example-code>

Особенно, если вы копируете / вставляете этот код из файла (или включаете его в препроцессор), было бы просто иметь нужные символы в вашем XML-файле, не путая их с тегами / атрибутами XML. Как уже упоминалось @paary, другие распространенные случаи использования включают в себя встраивание URL-адресов, содержащих амперсанды. Наконец, даже если данные содержат только несколько специальных символов, но данные очень и очень длинные (скажем, текст главы), было бы хорошо, если бы вы не редактировали эти несколько сущностей при редактировании своего XML-файла. ,

(Я подозреваю, что все сравнения с комментариями вводят в заблуждение / бесполезно.)

не-только-йети
источник
41

Мне когда-то приходилось использовать CDATA, когда мой элемент xml требовал хранения HTML-кода. Что-то вроде

<codearea>
  <![CDATA[ 
  <div> <p> my para </p> </div> 
  ]]>
</codearea>

Таким образом, CDATA означает, что он будет игнорировать любой символ, который в противном случае может быть интерпретирован как тег XML, такой как <и> и т. Д.

октан
источник
2
Не «тег», а элемент в первом предложении.
Людовик Куты
32

Содержащиеся в нем данные не будут анализироваться как XML, и поэтому не обязательно должны быть действительными XML или могут содержать элементы, которые могут выглядеть как XML, но не являются таковыми.

fbrereto
источник
16

Из Википедии:

[В] XML-документе или внешнем разобранном объекте раздел CDATA - это раздел содержимого элемента, помеченный для синтаксического анализатора как интерпретируемый только как символьные данные, а не как разметка.

http://en.wikipedia.org/wiki/CDATA

Таким образом: текст внутри CDATA воспринимается синтаксическим анализатором, но только как символы, а не как узлы XML.

Chdid
источник
13

В качестве другого примера его использования:

Если у вас есть RSS-канал (XML-документ) и вы хотите включить некоторую базовую кодировку HTML в отображение описания, вы можете использовать CData для его кодирования:

<item>
  <title>Title of Feed Item</title>
  <link>/mylink/article1</link>
  <description>
    <![CDATA[
      <p>
      <a href="/mylink/article1"><img style="float: left; margin-right: 5px;" height="80" src="/mylink/image" alt=""/></a>
      Author Names
      <br/><em>Date</em>
      <br/>Paragraph of text describing the article to be displayed</p>
    ]]>
  </description>
</item>

RSS Reader извлекает описание и отображает HTML-код в CDATA.

Обратите внимание - не все HTML-теги работают - я думаю, что это зависит от используемой вами программы чтения RSS.


И как объяснение того, почему в этом примере используются CData (а не соответствующие теги pubData и dc: creator): это для отображения веб-сайта с использованием виджета RSS, для которого у нас нет реального элемента управления форматированием.

Это позволяет нам указать высоту и положение включенного изображения, правильно отформатировать имена и дату автора и т. Д. Без необходимости создания нового виджета. Это также означает, что я могу написать это и не добавлять их вручную.

LadyCygnus
источник
9

CDATA расшифровывается как Character Data. Вы можете использовать это для экранирования некоторых символов, которые в противном случае будут рассматриваться как обычный XML. Данные внутри этого не будут проанализированы. Например, если вы хотите передать URL-адрес, содержащийся &в нем, вы можете использовать CDATA для этого. В противном случае вы получите ошибку, поскольку она будет проанализирована как обычный XML.

paary
источник
6

Он используется для хранения данных, которые в противном случае могут рассматриваться как xml, поскольку содержат определенные символы.

Таким образом, данные внутри будут отображаться, но не интерпретироваться.

Ikke
источник
5

Он экранирует строку, которую нельзя передать в XML как обычно:

Пример:

Строка содержит "&" в нем.

Тебе нельзя:

<FL val="Company Name">Dolce & Gabbana</FL>

Следовательно, вы должны использовать CDATA:

<FL val="Company Name"> <![CDATA["Dolce & Gabbana"]]> </FL>
HoangYell
источник
1

Обычно используется для встраивания пользовательских данных, таких как изображения или звуковые данные, в документ XML.

Johan
источник
3
Хотя вы можете поместить текстовые двоичные данные в раздел CDATA, вам это не нужно, потому что CDATA не имеет ничего общего с двоичными данными.
Джоэл Мюллер
1

Cdata - это данные, которые вы, возможно, захотите передать в синтаксический анализатор xml, но они все еще не интерпретируются как xml.

Скажем, например: - У вас есть XML, который содержит объект вопроса / ответа. Такие открытые поля могут иметь любые данные, которые строго не подпадают под базовый тип данных или определенные пользователем типы данных xml. Нравится - Это правильный тег для комментария xml? .-- У вас может быть требование передать его в том виде, в каком оно есть, без интерпретации анализатором xml как другого дочернего элемента. Здесь Cdata приходит на помощь. Объявляя Cdata, вы говорите парсеру, что не следует обрабатывать данные, обернутые в XML (хотя они могут выглядеть как один)

хаотичность
источник
0

Обратите внимание, что CDATAконструкция необходима только при размещении текста непосредственно в текстовом файле XML.

То есть, вам нужно только использовать, CDATAесли вы вручную печатаете или программируете текст XML напрямую.

Любой текст, введенный с использованием API процессора DOM или SimpleXML, будет автоматически экранирован, чтобы предотвратить нарушение правил содержимого XML.

Патанджали
источник