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):

  1. Может ли содержимое этого элемента включать дочерние элементы?
  2. Если да, должны ли имена этих элементов совпадать с именами элементов в 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 Опять же, обратите внимание, что в спецификации сказано, что возможно вкрапления. Вот полное определение:

3.2.2 Смешанный контент

[Определение: тип элемента имеет смешанное содержимое, если элементы этого типа могут содержать символьные данные, необязательно перемежающиеся с дочерними элементами.]

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