
Это очередная статья в цикле «Основы 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 сущности. Это больше («>» — <), меньше («<» — >) и амперсанд («&» — &). При желании вы можете создать неограниченное количество сущностей, используя данный способ. В качестве значений могут быть не только слова, но и целые предложения значительного объема.
Подключение 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!
Хорошая статья! Завтра экзамен. Салют!
Спасибо за комментарий! Желаю удачно все сдать:)
"+" и "?" в DTD выполняют такую-же функцию как и в регулярных выражениях :-)
+ — Один элемент и более
? — может есть, а может и нет :-)
Прикольно!
Написал как есть:) Нужно продолжить писать статьи на эту тему, а то что-то я ударился в сторону WordPress и совсем забыл об XML и XSLT. В ближайшее время выпущу новую статью по XML, поэтому подписывайтесь на новости блога:)
Спасибо, Дмитрий! Статьи по XML хороши:) Экзамен 18-ого… Единственное, чего не нашел — технологии DOM и SAX:)
Спасибо, Павел! Давно хочу продолжить работу над данным разделом, а также всеми остальными, но из-за нехватки времени никак не получается это сделать. Как только появится свободная минутка — сразу же займусь написанием новых статей:)
Спасибо дружище за статью
Спасибо, хороший сайт и объяснения!