Декларация DTD используется для отображения структуры XML-документа и состоит из объявлений используемых в документе типов элементов, атрибутов и сущностей.
Типы элементов задаются с помощью строк:
<!ELEMENT тип_элемента содержание>
Содержание — либо тип содержимого элемента (модель элемента), либо список типов элементов, вложенных в данный элемент в иерархической структуре:
<!ELEMENT тип_элемента (#PCDATA)>
<!ELEMENT тип_элемента (список_типов_вложенных_элементов)>
Модель элемента (#PCDATA) означает, что элемент может состоять только из символьных данных, модель ANY допускает любые данные, а модель EMPTY соответствует пустому (бесконтейнерному) элементу. Возможен также смешанный тип содержимого, когда элемент может содержать и символьные данные, и вложенные элементы (т.е. одним из пунктов списка вложенных элементов будет #PCDATA).
Пример описания типов элементов в DTD (назначение знаков + и ?, имеющихся в примере, будет пояснено ниже):
<!ELEMENT metadata (name, authors, type, description, 
    owner?, year?, price?)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT authors (#PCDATA)+>
<!ELEMENT type (#PCDATA)>
<!ELEMENT description (#PCDATA)>
<!ELEMENT owner (#PCDATA)>
<!ELEMENT year (#PCDATA)?>
<!ELEMENT price (#PCDATA)?>
Атрибуты служат для характеристики типов элементов. С помощью типов элементов и значений их атрибутов можно сортировать части документа, устанавливать между ними отношения, выделять нужные экземпляры и т.п. Объявление атрибутов, относящихся к определенному типу элементов, имеет вид:
<!ATTLIST тип_элемента имя_атрибута тип_атрибута статус>
Атрибуты могут быть строкового, маркерного или нумерованного типов. Строковый тип обозначается CDATA и соответствует типу данных string, т.е. атрибут типа CDATA в документе должен быть записан в виде строки символов в кавычках. Маркерный тип отличается от строкового тем, что на значения атрибута маркерного типа накладываются некоторые ограничения. Имеется несколько вариантов ограничений и для каждого из них выделен определенный идентификатор, записываемый в поле тип_атрибута. Значения атрибута нумерованного типа либо выбираются из конечного списка значений, записанного в поле тип_атрибута, либо представляют собой тексты предопределенного формата (например, форматов HTML, SGML и т.п.), на что указывает запись NOTATION список_форматов в поле тип_атрибута.
Статус может иметь четыре значения (варианта). Вариант #REQUIRED используется, если для соответствующих типов элементов в документе запись значения данного атрибута обязательна. Вариант #IMPLIED используется, если значение атрибута в документе использовать необязательно. Значение "значение_по_умолчанию", записываемое в поле статус, есть значение атрибута, используемое по умолчанию. В случае варианта #FIXED "значение_по_умолчанию" никакое другое значение атрибута, кроме указанного по умолчанию, в документе использовать нельзя.
Отметим, что в одной записи может быть описано более одного атрибута.
Приведем несколько примеров объявлений атрибутов. Предварительно напомним, что размеченный текст в элементе "Документ" состоит из элементов, помещаемых в контейнеры, т.е. между парой тегов. Например, такими тегами могут быть <item> и </item>, <termin> и </termin>, <description> и </description>, <examples> и </examples>. Значения атрибутов могут включаться в открывающий тег, как это сделано для тега <T1> в следующем примере.
Пример 1
<!ATTLIST T1 A1 CDATA #REQUIRED>
Здесь элемент типа T1 имеет атрибут A1, его значения относятся к типу данных CDATA, значение атрибута A1 должно быть указано в открывающем теге каждого элемента типа T1, например:
<T1 A1='high-level'> Программный комплекс CATIA </T1>
Пример 2
<!ATTLIST book title CDATA #REQUIRED author CDATA #IMPLIED 
    publisher CDATA #REQUIRED>
Элемент типа book имеет три атрибута строкового типа, значения атрибута author указывать необязательно, два других атрибута обязательны.
Пример 3
<!ATTLIST ray color (red|green|blue) "red">
Атрибут color элемента типа ray может обозначать красный, зеленый или синий цвет, по умолчанию задается красный цвет.
Сущности используют для присвоения псевдонимов некоторым блокам данных, что позволяет в документе лаконично ссылаться на эти данные, на данные из ранее разработанных документов, на блок многократно используемых данных, включать в XML-документ данные различных форматов, например, графические данные.
Блок данных может быть внутренним примитивом, т.е. фразой, непосредственно записываемой в объявлении:
<!ENTITY псевдоним "фраза">
Например, с помощью ENTITY можно вводить аббревиатуры для словосочетаний, как в следующей строке:
<!ENTITY IEEE "Institute of Electrical and Electronics Engineers">
В документе записи вида &IEEE; будут заменены на блок XML-данных Institute of Electrical and Electronics Engineers.
Блок XML-данных может быть внешним файлом, и тогда ссылка есть указание адреса файла:
<!ENTITY псевдоним SYSTEM "адрес_файла">
Например:
<!ENTITY Приложение SYSTEM "http://ifc.com/addition1.xml">
В документе записи вида &Приложение; будут заменены на XML-содержимое файла с указанным адресом.
Несколько сложнее выглядит включение в XML-документ внешних не XML-данных. В этом случае строка ссылки имеет вид:
<!ENTITY псевдоним SYSTEM "адрес_файла" NDATA имя_нотации>
Здесь имя_нотации — описание формата не XML-данных или адрес программы для обработки этих данных.
Например, если нужно внутри элемента типа item разместить рисунок, данные о котором находятся в файле fig.bmp в формате BMP, то в DTD нужно добавить строки
<!ELEMENT place EMPTY>
<!ATTLIST place par ENTITY #REQUIRED>
<!NOTATION BMP SYSTEM "pbrush.exe">
<!ENTITY figure SYSTEM "fig.bmp" NDATA BMP>
Первые две строки объявляют пустой элемент place с атрибутом par маркерного типа, в котором используется идентификатор ENTITY. Назначение идентификатора ENTITY — ограничивать возможные значения атрибута значениями псевдонимов, введенных в DTD. Две следующие строки задают месторасположение графических данных (файл fig.bmp) и способ их обработки (программа pbrush.exe). В самом документе в контейнерах элементов типа item достаточно записать следующую строку, чтобы при визуализации элементов типа item появилось изображение в соответствии с данными файла fig.bmp:
<place par="figure" />
Блок данных, фигурирующий в DTD, может быть списком атрибутов, который используется в DTD многократно. Его целесообразно заменить псевдонимом, перед которым нужно записать символ %:
<!ENTITY % имя_перечня 'список_атрибутов'>
Список атрибутов записывается по тем же правилам, что и в объявлении ATTLIST.
Нужно сделать ряд дополнительных пояснений особенностей языка XML.
Прежде всего рассмотрим, как в определении типов элементов оформляется содержание в виде списка типов элементов нижнего уровня, вложенных в элемент верхнего уровня.
Во-первых, этот список может быть представлен перечислением типов элементов нижнего уровня в круглых скобках через запятую. Например:
<!ELEMENT item (termin,description,examples)>
В этом случае вложенные типы termin, description, examples должны обязательно присутствовать в каждом элементе верхнего уровня типа item, причем по одному разу и в том же порядке, как они представлены в списке.
Во-вторых, элементы списка можно отделять не запятыми, а символом "вертикальная черта":
<!ELEMENT item (termin|description|examples)>
Теперь в элементе типа item может присутствовать единственный вложенный элемент одного из типов termin, description, examples.
В обоих рассмотренных случаях можно варьировать характером ограничений, используя после элементов списка (или после скобки, закрывающей часть или весь список) соответствующие знаки +, * и ?. Знак + означает, что элемент соответствующего типа (или группа элементов, типы которых перечислены в списке, заключенном в круглые скобки) может присутствовать в элементе верхнего уровня один или более раз. Знак * отличается от знака + тем, что указываемый им тип элемента может отсутствовать в элементе верхнего уровня. Знак ? отличается от знака * тем, что позволяет использовать вложенный элемент не более одного раза. Так, в нашем примере благодаря знаку ? после элемента типа examples, можно не во всех пунктах словаря приводить примеры, что и сделано для пункта с атрибутом number = '_14'. Если бы нам требовалось разрешить произвольные число и порядок следования вложенных элементов, то нужно было бы использовать описание элемента типа item в виде
<!ELEMENT item (termin|description|examples)+>