XML-проверка #PCDATA
У меня есть этот простой XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE input[
<!ELEMENT input (#PCDATA)>
<!ELEMENT file (#PCDATA)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT type (#PCDATA)>
]>
<input>
This is the content <file><name>test.png</name><type>Image</type></file>
</input>
Я ожидаю, что это будет действительным, но некоторые онлайн-валидаторы сообщают, что это недействительно, потому что элементы input и file содержат нетекстовые узлы.
Если я удалю элемент файла внутри элемента ввода, то полученный XML будет считаться действительным, поэтому я ожидаю, что "нетекстовые узлы" являются дочерними элементами (файл на входе, имя и тип файла).
Я ожидаю, что это будет действительным, потому что спецификация XML для элемента указывает, что элемент действителен, если он соответствует одному из набора условий, одно из которых:
Объявление соответствует Mixed, а содержимое (после замены любых ссылок на объекты их заменяющим текстом) состоит из символьных данных (включая разделы CDATA), комментариев, PI и дочерних элементов, типы которых соответствуют именам в модели содержимого.
Обратите внимание на "и дочерние элементы..." ближе к концу.
А продукция для смешанного - это:
Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*'
| '(' S? '#PCDATA' S? ')'
Второй случай - это то, что у меня есть для ввода и файла:
(#PCDATA)
Требование валидности для смешанного контента состоит в том, что дочерние элементы могут существовать, если их имена совпадают с именами в модели контента, что они и делают.
Я неправильно понимаю спецификацию или эти валидаторы неверны?
Если я удалю объявления элементов файла, имени и типа из DTD, но оставлю дочерние элементы в содержимом элемента ввода, то я получаю дополнительные ошибки проверки, указывающие на отсутствие объявления этих типов. Я ожидаю появления этих ошибок, потому что требование проверки состоит в том, чтобы имена дочерних элементов совпадали с именами в модели содержимого, а после удаления этих объявлений они не соответствовали именам в модели содержимого.
Но есть и другие валидаторы, которые сообщают, что XML действителен даже без деклараций элементов файла, имени и типа в DTD. Это тоже кажется ошибкой валидаторов, поскольку требование валидации ясно говорит, что имена дочерних элементов должны совпадать с именами в модели содержимого, чего они не делают, когда эти объявления элементов удаляются.
Я знаю, что существуют различные реализации проверки XML, и не все они работают одинаково, поэтому все они не могут быть строго правильными. Меня больше всего интересует строго правильное понимание спецификации.
В строгом соответствии с требованиями действительности элемента с содержанием
(#PCDATA)
:
- Может ли содержимое этого элемента включать дочерние элементы?
- Если да, должны ли имена этих элементов совпадать с именами элементов в DTD?
Спецификация только, кажется, требует, чтобы имена дочерних элементов совпадали с именами элементов в DTD, но я думаю, что разумно содержимое и атрибуты таких элементов также должны соответствовать объявлениям в DTD, но в спецификации на самом деле этого не говорится. Итак, опять же, в строгом соответствии с требованиями действительности спецификации, содержимое и атрибуты дочернего элемента элемента с содержимым
(#PCDATA)
сопоставить их объявления в DTD? Если да, то где в спецификации это сказано?
Наконец, существует ли какой-либо простой в использовании (онлайн или устанавливаемый в Linux) XML-валидатор, который строго соответствует спецификации, которую вы можете порекомендовать?
1 ответ
Объявление вашего элемента,
<!ELEMENT input (#PCDATA)>
технически квалифицируется как допускающее смешанное содержимое, но не позволяет смешивать какие-либо элементы.
В разделе, который вы цитируете, говорится, что смешанный контентможет содержать символьные данные, необязательно перемежаемые дочерними элементами. Это подтверждается производством в этом разделе. Видеть
^^^
ниже, который позволяет смешивать элементы, если это предусмотрено Name
:
Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*'
^^^^^^^^^^^^^^^^^
| '(' S? '#PCDATA' S? ')'
Однако ваше объявление фактически не допускает элементов. Если вы хотите такие элементы, как
file
разрешено смешивать, вместо этого объявить
input
как это:
<!ELEMENT input (#PCDATA|file)*>
Обновите, чтобы учесть последующие комментарии
Любые
&
и
<
символы, которые появляются в проанализированных символьных данных, будут проанализированы: то есть интерпретироваться как разметка. Применяются правила правильного формата, и во время проверки проанализированная разметка должна соответствовать правилам грамматики, заданным схемой. Элемент только с
#PCDATA
в своей модели содержимого неявно не допускает вкрапления элементов, которые не упоминаются в модели содержимого.
В разговорной речи смешанный контент обычно подразумевает наличие вкраплений элементов; технически смешанный контент может содержать ноль или более элементов1. В любом случае документ недействителен, если элементы перемежаются анализируемыми данными, но не указаны в модели содержимого.
1 Опять же, обратите внимание, что в спецификации сказано, что возможно вкрапления. Вот полное определение:
[Определение: тип элемента имеет смешанное содержимое, если элементы этого типа могут содержать символьные данные, необязательно перемежающиеся с дочерними элементами.]