PCDATA против CDATA в XML DTD

В XML DTD - при определении элемента мы используем #PCDATA, чтобы сказать, что этот элемент может содержать любой разбираемый текст. При определении атрибута мы используем CDATA, чтобы сказать, что его значением могут быть любые символьные данные.

CDATA, используемый в XML, - это то, что не анализируется синтаксическим анализатором XML (escape-последовательность из нескольких символов). Последовательно, когда мы используем CDATA для определения атрибута; парсер не должен его анализировать. Но это так!

Тогда, почему нельзя было использовать PCDATA вместо CDATA для определения атрибутов?

Обновление - это было сохранено для обратной совместимости с SGML. В чем причина такого именования в SGML?

2 ответа

При использовании в объявленном значении атрибута CDATA относится к фактическому значению атрибута (символьные данные), а не к контексту, в котором он анализируется. С другой стороны, при разборе элементов нам необходимо различать символьные данные без разметки (CDATA) и анализируемые символьные данные, где разделители ожидаются (PCDATA) .

На первый взгляд это кажется произвольным, но это не так (см. Здесь и здесь).

В SGML спецификация значения атрибута может быть заключена в кавычки (литерал значения атрибута) или не заключена в кавычки (значение атрибута).

attribute value specification = attribute value literal | attribute value

Когда атрибут не заключен в кавычки, разрешены только NAME-символы, и это может быть дополнительно ограничено для некоторых объявленных значений, таких как NUMBER.

Содержимое литерала значения атрибута, с другой стороны, представляет собой последовательность заменяемых символьных данных, заключенных в разделители LIT/LITA (двойные и одинарные кавычки, соответственно, в эталонном синтаксисе ссылки).

attribute value literal =
   ( LIT , replaceable character data *, LIT) | 
   ( LITA , replaceable character data *, LITA)

Заменяемые символьные данные "похожи на CDATA, за исключением того, что ссылки на сущности и символьные ссылки распознаются" (Goldfarb, SGML Handbook).

Отсюда следует, что замена ссылок на сущности в литералах значения атрибута не зависит от объявленного значения атрибута. Поэтому, если у вас есть <!ENTITY foo "bar"> а также <elem attr="&foo;"> ссылка на сущность &foo; будет проанализирован в контексте заменяемых символьных данных (режим распознавания LIT), давая <elem attr=bar>, Не имеет значения, если attr объявляется как CDATA, NAME или что-то еще.

Обновить

Нет необходимости говорить, что сущности в атрибуте должны быть проанализированы, поскольку все типы атрибутов имеют одинаковые правила синтаксического анализа: если значение атрибута начинается с кавычки (LIT), то сущности распознаются (заменяемые символьные данные) и значение заканчивается, когда найдена соответствующая конечная кавычка.

Здесь CDATA означает, что действительный атрибут должен содержать произвольные символьные данные после расширения сущностей. Если бы атрибут был объявлен как NUMBER, он должен был бы содержать числовые символы (или объекты, расширенные до числовых символов).

В приведенном выше примере атрибут CDATA со значением "&foo;" эквивалентно "bar", так же, как атрибут NUMBER со значением "&#48;" эквивалентно "0" (хотя последовательность "&#48;" содержит символы, отличные от числовых).

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

Синтаксический анализ, который вы, скорее всего, наблюдаете (например, разрешаются ссылки на сущности), происходит из нормализации значения атрибута.

Другие вопросы по тегам