XML DTD — проверка грамматики XML-документов (валидация) при помощи DTD

Logo
XML DTD - проверка грамматики XML-документов (валидация) при помощи DTD

Это очередная статья в цикле «Основы XML» и в ней мы рассмотрим основы описания структуры XML данных при помощи DTD. Это довольно таки старый способ описания структуры XML-документов, но он до сих пор используется, поэтому мы его все же рассмотрим.

Также хочу отметить, что это отличный способ показать, как в XML идет проверка содержимого документа, его грамматики и т.д. Более новый и совершенный способ описания структуры XML-документов с использованием технологии XML Schema мы рассмотрим в следующей статье, ну а пока перейдем непосредственно к изучению DTD XML.

В рамках данной статьи мы рассмотрим сразу несколько важных моментов. Это что такое XML DTD и для чего он нужен, поговорим о недостатках DTD, а также научимся самостоятельно составлять собственный DTD для валидации XML-документов. Все это, как обычно, будет изложено пошагово, максимально кратко и понятно с целью экономии вашего времени.

Итак, начнем.

Что такое DTD в XML и для чего он нужен

DTD – это язык описания, который позволяет нам определить, какие элементы должны быть в XML-документе, сколько раз они должны повторяться, какие атрибуты должны быть у этих элементов, какие атрибуты обязательные и какие не обязательные, а также какие сущности могут использоваться в документе. Подробнее про конструкции XML читайте в статье «Элементы, теги и атрибуты XML».

Если говорить кратко, то DTD в XML используется для проверки грамматики документа и соответствия его стандарту (тому, который придумал разработчик или вы сами). Это позволяет парсеру (обработчику) на этапе обработки определить, соответствует ли документ нашим требованиям. То есть, проходит валидация XML-документа.

Необходимость проверки грамматики XML-документов заключается в следующем:

  • XML-документ может быть предназначен не для вашей системы.
  • XML-документ может содержать неправильные данные.
  • XML-документ может содержать ошибки в структуре (Разметка и структура XML документов).

Итак, мы разобрались с тем, что такое XML DTD и зачем он нужен. Теперь давайте кратко рассмотрим недостатки DTD, после чего перейдем непосредственно к рассмотрению процесса создания DTD файлов для валидации XML-документов.

Недостатки XML DTD

  • Отличный от XML синтаксис языка. Это вызывает множество проблем, таких как, например, проблемы с кодировкой или невозможность отслеживать ошибки.
  • Нет проверки типов данных. В DTD есть только один тип – строка.
  • В DTD нет пространств имен. Нельзя поставить в соответствие документу два и более DTD описаний.

Это был краткий список недостатков DTD, которые с успехом исправлены в XML схемах, о которых мы поговорим в следующих статьях.

Объявление элементов, атрибутов и сущностей в DTD. Модификаторы «*», «?», «+»

Для объявления элементов, атрибутов и сущностей в DTD используются специальные декларации и модификаторы. Чтобы подробно во всем разобраться, давайте для начала рассмотрим теоритическую информацию, а затем во второй части статьи перейдем к практическим примерам.

Определение элемента XML и последовательности элементов XML

<!ELEMENT название элемента (что может содержать)>

Пример

<!ELEMENT book (title, author, price, description)>

Элемент book содержит по одному элементу title, author, price и description.

Альтернативы элементов

<!ELEMENT название элемента (элемент 1, элемент 2, (элемент 3 | элемент 4 | элемент 5))>

Пример

<!ELEMENT pricelist (title, price, (author | company | sample))>

Элемент pricelist содержит элементы title, price и один элемент из трех на выбор – author, company либо sample.

Пустые элементы

<!ELEMENT элемент EMPTY>

Пример

<!ELEMENT none EMPTY>

Элемент none должен быть пустым.

Объявление атрибута

<!ATTLIST элемент
атрибут 1 CDATA #REQUIRED
атрибут 2 CDATA #IMPLIED
>

Пример

<!ATTLIST pricelist
id CDATA #REQUIRED
name CDATA #IMPLIED
>

Элемент pricelist может содержать два атрибута – атрибут id и атрибут name. При этом атрибут id является обязательным, так как указано #REQUIRED, а атрибут name – не обязательным (указано #IMPLIED). В свою очередь CDATA указывает обработчику, что разбирать содержимое атрибутов не нужно.

Определение сущностей

<!ENTITY сущность "что подставлять">

Пример

<!ENTITY myname "Дмитрий Денисов">

Если встретится сущность «&myname;», то вместо нее автоматически подставится «Дмитрий Денисов».

Модификаторы (объясняют повторения элементов)

* — ноль или много.
? – ноль или один.
+ — один или много.

Пример

<!ELEMENT books (book+)>

Элемент books может содержать один или более элементов book.

Теперь давайте рассмотрим, как это все выглядит на более практических примерах.

Создание DTD-файла для валидации XML-документа на примере прайс-листа книг

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

<?xml version="1.0" encoding="utf-8"?>
<pricelist>
<book>
<title>Книга 1</title>
<author>&myname;</author>
<price>Цена 1</price>
<description>Описание</description>
</book>
</pricelist>

Конечно, вышеприведенный пример не является пределом мечтаний, но для примера вполне сойдет. Как видно с примера, у нас есть корневой элемент pricelist, который содержит вложенные элементы book. Внутри элементов book находятся элементы title, author, price и возможно description, которые могут содержать какие-то текстовые данные.

Для валидации данного прайс-листа мы можем использовать DTD-документ следующего содержания.

<!ELEMENT pricelist (book+)>
<!ELEMENT book (title, author+, price, description?)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ELEMENT description (#PCDATA)>
<!ENTITY myname "Дмитрий Денисов">

Теперь разберем все более подробно.

  • <!ELEMENT pricelist (book+)> — декларируем корневой элемент books и в скобках указываем, что он может содержать. В данном случае он может содержать один или более элементов book (плюсик означает один или более, см. выше).
  • <!ELEMENT book (title, author+, price, description?)> — определяем элемент book. Элемент book может содержать один элемент title, один или более элементов author (плюсик), один элемент price и один или ни одного элемента description (знак вопроса).
  • <!ELEMENT title (#PCDATA)> — определяем элемент title. В качестве содержимого элемента указываем #PCDATA. Это означает, что анализатор обязан разбирать то, что находится внутри этого элемента.
  • Аналогичным образом определяем элементы author, price, description.
  • <!ENTITY myname «Дмитрий Денисов»> — определяем сущность. Сначала пишем саму сущность, а затем в кавычках то, что будет выводиться на ее месте. По умолчанию в XML определено только 3 сущности. Это больше («>» — &lt;), меньше («<» — &gt;) и амперсанд («&» — &amp;). При желании вы можете создать неограниченное количество сущностей, используя данный способ. В качестве значений могут быть не только слова, но и целые предложения значительного объема.
Подключение DTD для валидации XML-документов

Декларативный способ

Данный способ очень редко используется, так как его суть состоит в создании самодостаточных документов. То есть, документ будет сразу содержать и DTD и XML. Для добавления DTD в XML используется следующая конструкция.

<!DOCTYPE DOCUMENT [ содержимое ]>

где вместо DOCUMENT указываем корневой элемент XML-документа.

Для наглядности рассмотрим пример готового самодостаточного документа с декларативным способом включения DTD.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE pricelist [
<!ELEMENT pricelist (book+)>
<!ELEMENT book (title, author+, price, description?)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ELEMENT description (#PCDATA)>
]>
<pricelist>
<book>
<title>Книга 1</title>
<author>Автор 1</author>
<price>Цена 1</price>
<description>Описание</description>
</book>
</pricelist>

Внешнее определение DTD — подключение DTD-документа

Суть данного метода состоит в том, чтобы подключить к XML-документу файл DTD при помощи следующей конструкции.

<!DOCTYPE DOCUMENT SYSTEM "file.dtd">

где DOCUMENT – указываем корневой элемент XML-документа.
file.dtd – ссылка на файл DTD.

Для наглядности рассмотрим следующий пример.

XML-документ

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE pricelist SYSTEM "file.dtd">
<pricelist>
<book>
<title>Книга 1</title>
<author>Автор 1</author>
<price>Цена 1</price>
<description>Описание</description>
</book>
</pricelist>

DTD файл

<!ELEMENT pricelist (book+)>
<!ELEMENT book (title, author+, price, description?)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ELEMENT description (#PCDATA)>

На этом данная статья подошла к концу. Все основные моменты при работе с XML DTD мы рассмотрели и, надеюсь, у меня получилось понятно все объяснить. Если вы не хотите пропустить выпуска других уроков по XML и XSLT, рекомендую подписаться на новостную рассылку, воспользовавшись формой ниже.

На этом все. Удачи вам и успехов в изучении XML!

Обнаружили ошибку? Выделите ее и нажмите Ctrl+Enter

Комментарии 8

  • DL-57

    Хорошая статья! Завтра экзамен. Салют!

  • Дмитрий

    Спасибо за комментарий! Желаю удачно все сдать:)

  • Сергей

    "+" и "?" в DTD выполняют такую-же функцию как и в регулярных выражениях :-)
    + — Один элемент и более
    ? — может есть, а может и нет :-)

    Прикольно!

  • Дмитрий

    Написал как есть:) Нужно продолжить писать статьи на эту тему, а то что-то я ударился в сторону WordPress и совсем забыл об XML и XSLT. В ближайшее время выпущу новую статью по XML, поэтому подписывайтесь на новости блога:)

  • Павел

    Спасибо, Дмитрий! Статьи по XML хороши:) Экзамен 18-ого… Единственное, чего не нашел — технологии DOM и SAX:)

  • Дмитрий

    Спасибо, Павел! Давно хочу продолжить работу над данным разделом, а также всеми остальными, но из-за нехватки времени никак не получается это сделать. Как только появится свободная минутка — сразу же займусь написанием новых статей:)

  • farZa

    Спасибо дружище за статью

  • Таня

    Спасибо, хороший сайт и объяснения!

Оставить комментарий

отменить ответ