В DTD для XML используются следующие типы правил: правила для элементов и их атрибутов, описания категорий(макроопределений), описание форматов бинарных данных. Все они описывают основные конструкции языка - элементы, атрибуты, символьные константы внешние файлы бинарных данных.
Для того, чтобы использовать DTD в нашем документе, мы можем или описать его во внешнем файле и при описании DTD просто указать ссылку на этот файл или же непосредственно внутри самого документа выделить область, в которой определить нужные правила. В первом случае в документе указывается имя файла, содержащего DTD- описания:
<?xml version="1.0" standalone="yes" ?> <! DOCTYPE journal SYSTEM "journal.dtd"> ...Внутри же документа DTD- декларации включаются следующим образом:
... <! DOCTYPE journal [ <!ELEMENT journal (contacts, issues, authors)> ... ]> ...В том случае, если используются одновременно внутренние и внешние описания, то программой-анализатором будут сначала рассматриваться внутренние, т.е. их приоритет выше. При проверке документа XML- процессор в первую очередь ищет DTD внутри документа. Если правила внутри документа не определены и не задан атрибут standalone ="yes" , то программа загрузит указанный внешний файл и правила, находящиеся в нем, будут считаны оттуда. Если же атрибут standalone имеет значение "yes", то использование внешних DTD описаний будет запрещено.
Например, для элемента <flower> можно определить следующее правило:
<!ELEMENT flower PCDATA>Ключевое слово ELEMENT указывает, что данной инструкцией будет описываться элемент XML. Внутри этой инструкции задается название элемента(flower) и тип его содержимого.
В определении элемента мы указываем сначала название элемента(flower), а затем его модель содержимого - определяем, какие другие элементы или типы данных могут встречаться внутри него. В данном случае содержимое элемента flower будет определяться при помощи специального маркера PCDATA( что означает parseable character data - любая информация, с которой может работать программа-анализатор). Существует еще две инструкции, определяющие тип содержимого: EMPTY,ANY. Первая указывает на то, что элемент должен быть пустым(например, <red/>), вторая - на то, что содержимое элемента специально не описывается.
Последовательность дочерних для текущего элемента объектов задается в виде списка разделенных запятыми названий элементов. При этом для того, чтобы указать количество повторений включений этих элементов могут использоваться символы +,*, ? :
<!ELEMENT issue (title, author+, table-of-contents?)>В этом примере указывается, что внутри элемента <issue> должны быть определены элементы title, author и table-of-contents, причем элемент title является обязательным элементом и может встречаться лишь однажды, элемент author может встречаться несколько раз, а элемент table-of-contents является опциональным, т.е. может отсутствовать. В том случае, если существует несколько возможных вариантов содержимого определяемого элемента, их следует разделять при помощи символа "|" :
<!ELEMENT flower (PCDATA | title )*>Символ * в этом примере указывает на то, что определяемая последовательность внутренних элементов может быть повторена несколько раз или же совсем не использоваться.
Если в определении элемента указывается "смешанное" содержимое, т.е. текстовые данные или набор элементов, то необходимо сначала указать PCDATA, а затем разделенный символом "|" список элементов.
Пример корректного XML- документа:
<?xml version="1.0"?> <! DOCTYPE journal [ <!ELEMENT contacts (address, tel+, email?)> <!ELEMENT address (street, appt)> <!ELEMENT street PCDATA> <!ELEMENT appt (PCDATA | EMPTY)*> <!ELEMENT tel PCDATA> <!ELEMENT email PCDATA> ]> ... <contacts> <address> <street>Marks avenue</street> <appt id="4"> </address> <tel>12-12-12</tel> <tel>46-23-62</tel> <email>info@j.com</email> </contacts>
<!ATTLIST article id ID #REQUIRED about CDATA #IMPLIED type (actual | review | teach ) 'actual' '' >В данном примере для элемента article определяются три атрибута: id, about и type, которые имеют типы ID(идентификатор), CDATA и список возможных значений соответственно. Всего существует шесть возможных типов значений атрибута:
<!ENTITY hello ' Мы рады приветствовать Вас!' >Программа-анализатор, просматривая в первую очередь содержимое области DTD- определений, обработает эту инструкцию и при дальнейшем разборе документа будет использовать содержимое DTD- компонента в том месте, где будет встречаться его название. Т.е. теперь в документе мы можем использовать выражение &hello; , которое будет заменено на строчку "Мы рады приветствовать Вас"
В общем случае, внутри DTD можно задать три типа макроопределений:
Внутренние макроопределения - предназначены для определения строковой константы, с их помощью можно организовывать ссылки на часто изменяемую информацию, делая документ более читабельным. Внутренние компоненты включаются в документ при помощи амперсанта &
В XML существует пять предустановленных внутренних символьных констант:
<!ENTITY logotype SYSTEM "/image.gif" NDATA GIF87A>Макроопределения правил - макроопределения параметров могут использоваться только внутри области DTD и обозначаются специальным символом %, вставляемым перед названием макроса. При этом содержимое компонента будет помещено непосредственно в текст DTD- правила
Например, для следующего фрагмента документа:
<!ELEMENT name (PCDATA)> <!ELEMENT title (PCDATA | name)*> <!ELEMENT author (PCDATA | name)*> <!ELEMENT article (title, author)*> <!ELEMENT book (title, author)*> <!ELEMENT bookstore (book | article)*> <!ELEMENT bookshelf (book | article)*>можно использовать более короткую форму записи:
<!ELEMENT name (PCDATA)> <! ENTITY %names 'PCDATA | name'> <!ELEMENT article (%names;)*> <!ELEMENT book (%names;)*> <!ENTITY %content 'book | article'> <!ELEMENT bookstore (%content;)*> <!ELEMENT bookshelf (%content;)*>Макроопределения часто используются для описания параметров в правилах атрибутов. В этом случае появляется возможность использовать одинаковые определения атрибутов для различных элементов:
<!ENTITY %itemattr 'id ID #IMPLIED src CDATA'> <!ENTITY %bookattr "ISDN ID #IMPLIED type CDATA'> <!ENTITY %artattr " size CDATA'> <!ELEMENT book (title, author,content)*> <!ATTLIST book %itemattr %bookattr;> <!ELEMENT article (title, author, content)*> <!ATTLIST article %itemattr %artattr;>
Если в качестве программы на стороне клиента используется верифицирующий XML-процессор, то информацию о типе можно передавать при помощи специально созданного для этого атрибута элемента, имеющего соответствующее DTD- определение. В процессе разбора программа-анализатор передаст значение этого атрибута клиентскому приложению, которое сможет использовать эту информацию должным образом. Например, чтобы указать, что содержимое элемента должно быть длинным целым, можно использовать следующее DTD- определение:
<!ELEMENT counter (PCDATA)> <!ATTLIST counter data_long CDATA #FIXED "LONG">Задав атрибуту значение по умолчанию LONG и определив его как FIXED, мы позволили тем самым программе-клиенту получить необходимую информацию о типе содержимого данного элемента, и теперь она может самостоятельно определить соответствие типа этого содержимого указанному в DTD- определении .
Вот пример XML- документа, в котором определяются и используются несколько элементов с различными типами данных:
<!ELEMENT price (PCDATA)> <!ATTLIST price data_currency CDATA #FIXED "CURRENCY"> <!ELEMENT rooms_num (PCDATA)> <!ATTLIST rooms_num data_byte CDATA #FIXED "BYTE"> <!ELEMENT floor (PCDATA)> <!ATTLIST floor data_byte CDATA #FIXED "INTEGER"> <!ELEMENT living_space (PCDATA)> <!ATTLIST living_space data_float CDATA #FIXED "FLOAT"> <!ELEMENT counter (PCDATA)> <!ATTLIST counter data_long CDATA #FIXED "LONG"> <!ELEMENT is_tel (PCDATA)> <!ATTLIST is_tel data_bool CDATA #FIXED "BOOL"> <!ELEMENT house (rooms_num, floor,living_space, is_tel, counter, price)> <!ATTLIST house id ID #REQUIED> ... <house id="0"> <rooms_num>5</rooms_num> <floor>2</floor> <living_space>32.5</living_space> <is_tel>true</is_tel> <counter>18346</counter> <price>34 р. 28 к.</price> </house> ...Как видно из примера, механизм создания элементов документа при этом нисколько не изменился. Все необходимая для проверки типов данных информация заложена в определения элементов внутри блока DTD.
В заключении хотелось бы отметить, что DTD предоставляет нам весьма
удобный механизм осуществления контроля за содержимым документа. На сегодняшний
день, практически все программы просмотра документов Интернет используют
DTD-правила. Однако это далеко не единственный способ проверки корректности
документа. В настоящий момент в W3 консорциуме находится на рассмотрении
новый стандарт языка описания структуры документов, называемый схемами
данных. Следующий раздел посвящен работе с ними.