Document Type Definition

В предыдущей лекции «Введение в XML», мы говорили, что XML документы могут быть двух типов:

В настоящее время World Wide Web Consortium (W3C) поддерживает две схемы: DTD (Document Type Definition) и XML Schema.

В данной лекции будет рассмотрена первая, более ранняя из этих двух схем – DTD. XML Schema будет рассмотрена в последующих лекциях.

Описание DTD выполнено в Рекомендации «Extensible Markup Language (XML) 1.0», т.е. в той же самой рекомендации, где описаны требования к XML документу.  

Задача DTD определить:

В дальнейшем, для изложения материала данной лекции мы будем использовать XML документ, представленный ниже, который описывает библиотеку книг по информационным технологиям:

  <?xml version="1.0" encoding="Windows-1251"?>
  <library>
     <books>
        <book  id="N1"  isbn="978-5-8459-1118-6" year="2008" issue="translation">
           <udk value="004.541.47"/>
           <authors>
              <author country="US">С. Граннеман</author>
           </authors>
           <title>Linux. Карманный справочник</title>
           <cover border="1" align="center" width="350" height="200"
                href="www.williamspublishing.com/covers/linux.gif"/>
           <publishing>Вильямс</publishing>
           <annotation>Область применения <scope>операционные системы</scope></annotation>
        </book>
        <book  id="N2"  isbn="5-314-00189-6" year="2000" issue="translation">
           <udk value="681.3" />
           <authors>
              <author country=”US”>К. Уилмер</author>
              <author country=”US”>А. Хоумер</author>
           </authors>
           <title>Dynamic HTML. Справочник</title>
           <cover border="1" align="center" width="350" height="200" 
                href="www.piter-press.ru/covers/dhtml.gif"/>
           <publishing>Питер</publishing>
           <annotation>Область применения <scope>Интернет</scope></annotation>
        </book>
        <book  id=”N3”  isbn="978-5-9775-0104-0" year="2007" issue=”original”>
           <udk value="681.3.06"/>
           <authors>
              <author country=”RU”>Д.Н. Колисниченко</author>
           </authors>
           <title>Ubuntu Linux</title>
           <cover border=”1” align=”center” width=”350” height=”200” 
                href=”www.bhv.ru/covers/ubuntu.gif”/>
           <publishing>БХВ-Петербург</publishing>
           <annotation>Область применения ОС Linux</scope></annotation>
        </book>
     </books>
  </library>
  

1 Объявление DTD в XML документе

Прежде чем начинать изучение правил составления DTD рассмотрим, как XML документ объявляет DTD. Это позволит сразу, по мере изучения DTD, опробовать разрабатываемые примеры на компьютере.

DTD, относительно XML документа, могут быть двух типов: внешними и внутренними. Также возможно вXML документе одновременно использовать оба типа DTD.

Для объявления DTD в XML документе используется предложение DOCTYPE, которое должно располагаться перед корневым элементом XML документа, а указываемое в нем имя DTD должно совпадать с именем корневого элемента. Предложение DOCTYPE имеет вид:

<!DOCTYPE имя_dtd  расположение_dtd >,

где: имя_dtd – имя схемы DTD, совпадающее с именем корневого элемента XML документа;

расроложение_dtd – описатель местоположения схемы DTD, вид которого зависит от типа DTD.

1.1  Внешний DTD

Внешний DTD находится в отдельном файле, который должен иметь расширение .dtd, например, library.dtd. Синтаксис предложения DOCTYPE в случае внешнего подключения принимает следующий вид:

<!DOCTYPE имя_dtd   >
 

где: URI – указание местоположения схемы DTD.

SYSTEM и PUBLIC – альтернативно используемые ключевые слова, применяемые по следующему алгоритму.

При указании SYSTEM анализатор должен найти DTD по явно указанному URI, например:

<!DOCTYPE  library SYSTEM “http://www.library.org/dtd/library.dtd”>

При указании PUBLIC считается, что будет использоваться публичный DTD, «хорошо знакомый» используемому обработчику XML документа. Предположим, что для библиотечных систем существует публичная схема DTD, расположенная на определенном сайте в Интернет. Если для работы с библиотечными XML документами используется не стандартный, а специализированный анализатор, то он может сам знать , где находится необходимая ему схема DTD. В этом случае не обязательно указывать точное URI расположения файла со схемой DTD, например:

<!DOCTYPE  library PUBLIC “world/library.dtd”>

Можно совместить описание РUBLIC с указанием конкретного расположения файла со схемой DTD. В этом случае, если анализатор не найдет публичного схему, он будет использовать схему, указанную по конкретному адресу, например:

  <!DOCTYPE  library PUBLIC "world/library.dtd" 
                            "http://www.library.org/dtd/library.dtd">
  

1.2 Внутренний DTD

Внутренний DTD включается непосредственно в тело XML документа. Предложение DOCTYPE в случае внутреннего подключения имеет следующий вид:

  <!-- DTD -->
  <!DOCTYPE  имя_dtd
  [
     содержание DTD
  ]>
  <!-- XML документ -->
  <library>
  . . .
  </library>
  > 
  

Содержание DTD располагается внутри квадратных скобок.

1.3 Одновременное использование внешнего и внутреннего DTD

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

В такой ситуации рекомендуется использовать внешний DTD, а необходимые изменения выполнить во внутреннем DTD.

Примечание. В случае возникновения конфликта между описаниями внешнего и внутреннего DTD приоритет имеют описания внутреннего DTD.

Синтаксис предложения DOCTYPE при одновременном использовании внешнего и внутреннего DTD имеет следующий вид:

  <!-- сначала внешний, а за ним внутренний DTD -->
  <!DOCTYPE имя_dtd   >
   [
     содержание внутреннего DTD
  ]>
  <!-- XML документ -->
  <library>
  . . .
  </library>
  > 
  

2 Объявление элементов

Для объявления элементов в DTD используется предложение ELEMENT, которое имеет следующий вид:

<!ELEMENT имя_элемента (модель_содержания) [EMPTY]>

где: имя_элемента – имя, под которым элемент может появляться в XML документе;

модель_содержания – описание правил вхождения одних элементов в другие;

EMPTY – необязательный параметр, применяемый для указания о том, что элемент должен быть пустым.

В DTD должны быть объявлены все элементы, которые можно будет использовать в XML документе. Также для каждого элемента должна быть определена модель содержания, позволяющая определить:

При построении модели содержания необходимо помнить, что описание вложенности выполняется только для  непосредственно нижележащего уровня. Так элемент, формирующий контейнер первого уровня, может описывать структуру не всех входящих в него элементов и контейнеров, а только элементов следующего за ним второго уровня. Элементы второго уровня описывают структуру элементов и контейнеров третьего уровня и т.д.

В модель содержания могут включаться элементы одного из четырех типов:

Такая классификация типов содержания элементов обусловлена, в первую очередь, возможностью включения в элемент текстовой информации.  Рассмотрим каждый из этих типов.

Элементный тип – состоит только из элементов и не может включать текст. В  представленном в начале лекции XML документе к данному типу относятся такие элементы как library, books, book.  

Модель содержания для элементного типа позволяет не только указать, какие элементы будут содержаться в элементе-контейнере, но задать их порядок и количество вложений (ни разу, один раз, много раз). Для задания множественности вложений используется набор специальных символов:

Пример описания элемента элементного типа:

  <!ELEMENT books (book+)> 
  <!ELEMENT book (udk, authors, publishing, annotation?)> 
  <!ELEMENT authors (author+)>  

В данном примере полагаем, что у книг, связанных с информационными технологиями, должен быть хотя бы один автор, а возможно и несколько авторов. Однако если бы разрабатывался DTD для библиотеки с художественными книгами, то  у книг, например, с народными сказками возможна ситуация, когда авторы не известны. В этом случае элемент book более правильно было бы объявить так

<!ELEMENT book (udk, authors?, publishing, annotation?)>

Текстовый тип включает только текст. В представленном примере к данному типу относятся такие элементы как author, title, publishing. Данный тип идентифицируется словом #PCDATA (parsed character data) в поле модели содержания. Пример описания элемента текстового типа:

<!ELEMENT author (#PCDATA)>

Смешанный тип может включать как текст, так и элементы. В представленном примере к данному типу относится элемент annotation. Пример описания элемента смешанного типа:

<!ELEMENT annotation (#PCDATA | scope)*>

На использование смешанного типа накладывается ряд ограничений:

Произвольный тип может включать любое содержание. Характеризуется словом ANY в поле модели содержания. Пример описания элемента произвольного типа:


<!ELEMENT имя_элемента ANY>

Создавать и использовать элементы произвольного типа обычно не рекомендуется.

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

Для объявления атрибутов в DTD используется предложение ATTLIST, которое имеет следующий формат:

  <!ATTLIST имя_элемента  имя_атрибута  типа_атрибута   способ_использования_атрибута
                        ["по умолчанию"]>
  

где: имя_элемента – параметр, определяющий имя элемента, которому принадлежит атрибут;
имя_атрибута – параметр, определяющий имя объявляемого атрибута;
типа_атрибута – параметр, определяющий тип, который атрибут может принимать, описывается в разделе 3.1;
способ_использования_атрибута – параметр, определяющий как атрибут может использоваться, и каким образом будет формироваться значение по умолчанию, описывается в разделе 3.3.

Правила использования умолчания зависят от значения, которое принимает параметр способ_использования_атрибута.

Если один элемент имеет несколько атрибутов, то можно каждый атрибут объявить отдельным предложением ATTLIST, например:

  <!ATTLIST book id ID #IMPLIED>
   <!ATTLIST isbn CDATA #REQUIRED>
  <!ATTLIST year CDATA #IMPLIED>
  

 а можно все атрибуты одного элемента объявить в одном предложении ATTLIST, например:

  <!ATTLIST book id ID #IMPLIED
                       isbn CDATA #REQUIRED
                       year CDATA #IMPLIED>
  

3.1 Тип атрибута

Возможные значения типов атрибута и их обозначения представлены в таблице 1.

Таблица 1 – Возможные значения типов атрибутов и их обозначения

Значение атрибута

Обозначение

Простой текст

CDATA

Предопределенное значение

(значение1 | значение2 | . . . | значениеN)

Уникальный идентификатор  

ID

Ссылка на ID

IDREF

Список ссылок ID

IDREFS

Текст без пробелов

NMTOKEN

Список текстов без пробелов

NMTOKENS

Сущность

ENTITY

Список сущностей

ENTITIES

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

Предопределенное значение. Атрибут может принимать только одно из  перечисленных значений. В примере XML документа атрибут issue указывает – является книга переводная (значение translation), или нет (значение original). Поэтому в DTD он должен быть объявлен следующим образом:

<!ATTLIST book  issue (translation | original)  #REQUIRED >

Уникальный идентификатор (ID). Используется для задания уникальной идентификации определенного элемента XML документа. Значение ID не может быть одинаковым ни для каких элементов в одном документе. В примере XML документа уникальным идентификатором должен быть атрибут id для элемента book. Поэтому в DTD он должен быть объявлен следующим образом:

<!ATTLIST book  id  ID  #REQUIRED>

Примечание. При указании атрибута с типом  ID значение способа использования атрибута может быть либо #REQUIRED, либо #IMPLIED.

Ссылка на ID (IDREF). Позволяет ссылаться на элемент, используя уникальный идентификатор, как адрес ссылки. Обеспечивается ссылка типа «один к одному».

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

  <author_book  idref=”N1”> С. Граннеман</author_book>
  <author_book  idref =”N2”>К. Уилмер</author_book>
  <author_book  idref =”N2”>А. Хоумер</author_book>
  <author_book  idref =”N3”>Д.Н. Колисниченко</author_book>
  <author_book  idref =”N33”>ХХХХХ</author_book>
  <author_book  idref =”N34”> ХХХХХ </author_book>
  <author_book  idref =”N35”> ХХХХХ </author_book>
  

В данном фрагменте считаем, что у автора ХХХХХ три книги в библиотеке с id равными N33, N34, N35.

Чтобы XML документ был действительным, в DTD необходимо сделать следующие объявления:

  <!ELEMENT author_book  EMPTY>
  <!ATTLIST author_book  idref  IDREF #REQUIRED>

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

Список ссылок на ID (IDREFS). Позволяет сформировать список ссылок к элементам, используя уникальные идентификаторы, разделенные пробелом, как адреса ссылок. Обеспечивается ссылка «один ко многим».

Изменим предыдущий фрагмент. Для каждого автора, имеющего несколько книг в библиотеке, не будем включать в XML документ соответствующее количество элементов author_book, в объявим в DTD новый элемент author_books:

  <!ELEMENT author_books  EMPTY>
  <!ATTLIST author_books  idrefs IDREFS #REQUIRED>

Теперь, в XML документе для автора ХХХХХ можно записать:

<author_books  id=”N33 N34 N35”> ХХХХХ </author_book>

Текст без пробелов (NMTOKEN). Значением атрибута данного типа в XML документе может быть любая символьная строка, не включающая символы разметки и пробелы. NMTOKEN  рекомендуется  применять для объявления атрибутов, являющихся идентификаторами.  Мы объявим с  типом NMTOKEN  атрибут country элемента author.

<!ATTLIST author country NMTOKEN #IMPLIED>

Список текстов без пробелов (NMTOKENS). Значением атрибута в XML документе может быть несколько строк типа NMTOKEN, разделены[ пробелом. Например, автор XXXXX родился в Канаде, а работает в США. Если мы хотим допустить возможность указания принадлежности автора к нескольким странам, то атрибут country элемента author следует в DTD объявить так

<!ATTLIST author country MNTOKENS #IMPLIED>

При таком объявлении следующая запись в XML документе примера будет действительной

<author country=”US CA”>ХХХХХ</author>

3.2 Сущности (ENTITY)

Хотя сущности относятся к типам атрибутов, которые были рассмотрены в предыдущем разделе (п. 3.1), все же вынесем их рассмотрение в отдельный раздел, поскольку описание этого типа атрибута достаточно большое по объему и самостоятельное по своему назначению.

Сущность – это абстрактное понятие, которое представляет следующие типы данных:

и определяет, каким образом анализатор XML может обращаться к этим данным.

Синтаксис объявления сущности в DTD в самом общем виде имеет формат, представленный ниже:

<!ENTITY имя_сущности “определение_сущности”>

где: имя_сущности – имя, под которым сущность может появляться в XML документе;
определение_сущности – зависит от типа информации сущности, а также от того, является сущность внутренней или внешней.

Значение информации, которую представляет сущность, может находиться вне сущности во внешнем файле (внешняя сущность), или присутствовать внутри определения сущности (внутренняя сущность). В случае внешней сущности параметр «определение_сущности» представляет собой URI, указывающий на местоположение информации сущности. В случае внутренней сущности параметр «определение_сущности» непосредственно содержит данные соответствующего типа.

3.2.1 Объявление текстовых сущностей и обращение к ним

 Текстовая сущность представляет собой фрагмент текста, замещающий в XML документе объектную ссылку, соответствующую значению «имя_сущности». Ограничений на размер фрагмента текста нет. Он может состоять из нескольких символов, а может быть большим документом.

Синтаксис текстовой сущности имеет вид:

- для внутренней сущности:

<!ENTITY имя_сущности “содержание”>

где: содержание – текстовое значение сущности;

- для внешней сущности:

<!ENTITY имя_сущности  >
 

где: ключевые слова SYSTEM и PUBLIC понимаются точно так же, как это описано для предложения DOCTYPE (см. п. 1.1);

URI – указание местоположения текстового файла с текстовым значением сущности, например,

<!ENTITY description SYSTEM “http://www.library.org/entities/text/description.txt”>

Обращение к текстовым сущностям в XML документе имеет следующий формат:

&имя_ссылки;

где: имя_ссылки должно совпадать с именем сущности, объявленным в DTD. Оно должно начинаться с символа амперсанд (&) и заканчиваться символом «точка с запятой» (;).

Текстовый объект удобно применять для замены повторяющихся одинаковых фрагментов в XML документах. Например, в XML документе примера элементы cover имеют вид:

     . . .
                                     <cover border=”1” align=”center” width=”350” height=”200” 
  href=www.williamspublishing.com/covers/linux.gif />
     . . .
                                     <cover border=”1” align=”center” width=”350” height=”200” 
  href=www.piter-press.ru/covers/dhtml.gif/>
     . . .
                                     <cover border=”1” align=”center” width=”350” height=”200” 
  href=www.bhv.ru/covers/ubuntu.gif/>
     . . .
	 

Мы видим, что они имеют одинаковые части, описывающие формат представления обложки книги. Объявляя в DTD текстовую сущность format

<!ENTITY format “border=’1’ align=’center’ width=’350’ height=’200’”>

можно элементы cover переписать в следующем виде:

     . . .
                                     <cover &format; href=www.williamspublishing.com/covers/linux.gif/>
     . . .
                                      <cover &format; href=www.piter-press.ru/covers/dhtml.gif />
     . . .

                                   <cover &format; href=www.bhv.ru/covers/ubuntu.gif/> . . .

3.2.2 Объявление параметрических сущностей и обращение к ним

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

Синтаксис и значения параметров параметрической сущности определяются аналогично, как и для текстовой сущности, но перед именем сущности ставится символ процента (%).

Внутренняя и внешняя параметрические сущности объявляется следующим образом:

- внутренняя:

<!ENTITY % имя_сущности “содержание”>

- внешняя:

<!ENTITY % имя_сущности  >
 

Обращение к параметрическим сущностям в DTD имеет следующий формат:

%имя_ссылки;

где: имя_ссылки должно совпадать с именем сущности, объявленным в DTD. Оно должно начинаться с символа процент (%) и заканчиваться символом «точка с запятой» (;).

Рассмотрим пример возможного применения параметрической сущности. Допустим нам надо описать три пустых элемента picture, image и graph, представляющих разного вида графическую информацию, но имеющих один и тот же набор атрибутов: border, align, width, height.

            Обычным образом объявление элементов и атрибутов выглядело бы, как показано ниже:

  <!ELEMENT picture EMPTY>
  <!ATTLIST picture
      border NMTOKEN #REQUIRED
      align (left | center | right) #REQUIRED “center”
      width NMTOKEN #REQUIRED
      height NMTOKEN #REQUIRED>
  <!ELEMENT image EMPTY>
  <!ATTLIST image
      border NMTOKEN #REQUIRED
      align (left | center | right) #REQUIRED “center”
      width NMTOKEN #REQUIRED
      height NMTOKEN #REQUIRED>
  <!ELEMENT graph EMPTY>
  <!ATTLIST graph
      border NMTOKEN #REQUIRED
      align (left | center | right) #REQUIRED “center”
      width NMTOKEN #REQUIRED
      height NMTOKEN #REQUIRED>
  

Объявление с использованием параметрической сущности будет выглядеть следующим образом:

  <!ENTITY % img “

    border NMTOKEN #REQUIRED     align (left | center | right) #REQUIRED     width NMTOKEN #REQUIRED     height NMTOKEN #REQUIRED”> <!ELEMENT picture EMPTY> <!ATTLIST picture %img;> <!ELEMENT image EMPTY> <!ATTLIST image %img;> <!ELEMENT graph EMPTY> <!ATTLIST graph %img;>

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

Для внутреннего DTD так делать нельзя. Параметрическая ссылка может заменять только целое объявление.

3.2.3 Объявление двоичных сущностей

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

Синтаксис объявления  двоичной сущности имеет следующий вид:

<!ENTITY имя_сущности  NDATA тип_файла>
 

где: имя_сущности, SYSTEM, PUBLIC и URI определяются так же, как и для текстовой сущности;
NDATA – признак двоичной сущности;
тип_файла – определяет тип двоичного файла, например gif, mp3, wav.

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

Синтаксис объявления  NOTATION имеет следующий вид:

<!NOTATION тип_файла  >
 

где: тип_файла – определяет тип двоичного файла, например, gif, mp3, wav;
SYSTEM и PUBLIC определяются так же, как и для текстовой сущности;
URI – задает местоположение программы, используемой для обработки двоичного файла.

Например, требуется обработать обложку книги, которая хранится в gif файле с помощью программы paint из ОС Windows:

  <!ENTITY pic SYSTEM http://www.williamspublishing.com/covers/linux.gif NDATA gif>
  <!NOTATION gif  SYSTEM “c:/Windows/system32/mspaint.exe”>

Примечание. Если анализатор XML знает, как обработать двоичный файл, он может использовать свой собственный механизм обработки, игнорируя объявление NOTATION.

3.2.4 Объявление символьных сущностей

В принципе для любого символа можно объявить сущность и в XML документе вместо символа использовать ссылку на сущность. Предположим, нам в XML документе по каким-то причинам нельзя использовать цифру 1, а значение атрибута value элемента number, должно быть равно 1. Используем символьную сущность, как показано ниже в примере:

  <?xml version="1.0"?>
  <!DOCTYPE number  [
  <!ELEMENT number  EMPTY>
  <!ATTLIST number  value CDATA #REQUIRED>
  <!ENTITY one "1">
  ]>
  <number  value="&one;" />
  

При просмотре данного XML документа, например в Internet Explorer, он будет иметь вид:

  <?xml version="1.0" ?> 
    <!DOCTYPE number (View Source for full doctype...)>
    <number value="1"
  />

Вместо ссылки one будет подставлен символ «1».

Пять символов, представленных в таблице 2, предопределены в XML. Поэтому их ссылки можно использовать в XML документе без объявления в DTD.

Таблица 2. Предопределенные символы.

Предопределенный символ

Символьное значение ссылки

Числовое значение ссылки

амперсант (&)

&amp;

&#38;

больше (>)

&gt;

&#62;

меньше (<)

&lt;

&#60;

апостроф (‘)

&quot;

&#34;

двойные кавычки (“)

&apos;

&#39;

3.3 Способы использования атрибутов

В предыдущем разделе, в примерах при объявлении атрибутов, мы неоднократно указывали способы использования атрибутов. Возможные способы использования атрибутов и их обозначения представлены в таблице 3.

Таблица 3 – Возможные способы использования атрибутов и их обозначения

Способ использования атрибута

Обозначение

По умолчанию

 

Обязательный

#REQUIRED

Фиксированный

#FIXED

Неявный

#IMPLIED

По умолчанию. Если для атрибута не указан способ его использования, то должно быть указано значение по умолчанию. В противном случае документ не будет действительным. Пример объявления атрибута со значением по умолчанию:

<!ATTLIST author country MNTOKEN “US”>

В случае отсутствия в XML документе примера в элементе author атрибута country  анализатор сам добавит атрибут country=”US”. Разработчик XML документа может изменить это значение, указав его явно.

#REQUIRED. Если атрибут объявлен как обязательный, то этот атрибут всегда должен присутствовать у указанного элемента в XML документе. В противном случае документ не будет действительным. Пример объявления обязательного атрибута:

<!ATTLIST book  isbn  CDATA  #REQUIRED>

#FIXED. Если документ указан как фиксированный, то его значение разработчик XML документа изменять не может. В противном случае документ не будет действительным. Пример объявления фиксированного атрибута:

<!ATTLIST library  url  CDATA  #FIXED  “www.library.org”>

В случае отсутствия атрибута url в элементе library анализатор сам добавит атрибут url=”www.library.org”.

#IMPLIED. Если атрибут не обязательный и не фиксированный, то он является неявным. Неявные атрибуты не имеют значения по умолчанию и не обязаны всегда появляться в элементе, для которого они объявлены. Пример задания неявного атрибута:

<!ATTLIST book  year  CDATA  #IMPLIED>

В случае отсутствия атрибута year в элементе book анализатор не будет вставлять этот атрибут, но XML документ все равно будет действительным.

4 Пример DTD

В этом разделе представлен DTD и соответствующий ему действительный XML документ (находятся здесь), включающий ряд измененный, по сравнению с начальным XML документом примера, сделанных с учетом возможностей рассмотренных в данной лекции.

Оба документа включают достаточный объем комментариев, позволяющих понять намерение разработчика при их создании.

4.1 DTD

<?xml
    version="1.0" encoding="Windows-1251"?>
  <!-- объявляем элементы -->
  <!ELEMENT library (book_catalog, author_catalog)>
  <!ELEMENT book_catalog (book*)>
  <!-- допускаем, что авторов, УДК и аннотации может не быть -->
  <!ELEMENT book (udk?, authors?, title, cover, publishing, annotation?)>
  <!ELEMENT udk EMPTY>
  <!ELEMENT authors (author+)>
  <!ELEMENT author (#PCDATA)>
  <!ELEMENT title (#PCDATA)>
  <!ELEMENT cover EMPTY>
  <!ELEMENT publishing (#PCDATA)>
  <!-- считаем, книга может охватывать несколько областей,
  например, операционноые системы и сети -->
  <!ELEMENT annotation (#PCDATA | scope)*>
  <!ELEMENT scope (#PCDATA)>
  <!ELEMENT author_catalog (author_book*)>
  <!ELEMENT author_book (#PCDATA)>
  <!-- объявляем параметрическую сущность, которую используем в этом DTD -->
  <!ENTITY % par "NMTOKEN #REQUIRED">
  <!-- объявляем атрибуты -->
  <!ATTLIST book 
    ID #REQUIRED
    CDATA #IMPLIED
    %par; 
    (translation | original) "translation">  <!-- позволяем задавать: переводная или не переводная книга -->
  <!ATTLIST udk value CDATA #IMPLIED>
  <!ATTLIST author country  %par;>  
  <!-- атрибуты представления обложки: ширина бордюра, выравнивание по горизонтали,
     ширина и высота картинки на обложке -->
  <!ATTLIST cover 
    border NMTOKEN "1"   
    align (left | center | right) "center"
    width %par;
    height %par;
    href CDATA #REQUIRED>
  <!ATTLIST author_book  idref IDREF #REQUIRED>
  <!-- объявляем текстовые сущности, которую используем 
  в XML документе для описания областей применения книг -->
  <!ENTITY an_linux "<scope>ОС Linux</scope>">
  <!ENTITY an_internet "<scope>Интернет</scope>">
  

            4.2 Действительный XML документ

  <?xml version="1.0" encoding="Windows-1251"?>
  <!DOCTYPE  library SYSTEM "e:\library.dtd">
  <library>
    <!-- каталог книг -->
    <book_catalog>
       <book  id="N1"  isbn="978-5-8459-1118-6" year="2008" issue="translation">
          <udk value="004.541.47" />
          <authors>
             <author country="US">С. Граннеман</author>
          </authors>

        <title>Linux. Карманный справочник</title>         <cover border="1" align="center" width="350" height="200"  href="www.williamspublishing.com/covers/linux.gif" />         <publishing>Вильямс</publishing>         <annotation>Область применения &an_linux;.</annotation>      </book>      <book  id="N2"  isbn="5-314-00189-6" year="2000" issue="translation">         <udk value="681.3" />         <authors>            <author country="US">К. Уилмер</author>            <author country="US">А. Хоумер</author>         </authors>         <title>Dynamic HTML. Справочник</title>         <cover border="1" align="center" width="350" height="200" href="www.piter-press.ru/covers/dhtml.gif"/>         <publishing>Питер</publishing>         <annotation>Область применения &an_internet;</annotation>      </book>      <book  id="N3"  isbn="978-5-9775-0104-0" year="2007" issue="original">         <udk value="681.3.06" />         <authors>            <author country="RU">Д.Н. Колисниченко</author>         </authors>         <title>Ubuntu Linux</title>          <cover border="1" align="center" width="350" height="200" href="www.bhv.ru/covers/ubuntu.gif" />         <publishing>БХВ-Петербург</publishing>         <annotation>Область применения &an_linux;</annotation>      </book>   </book_catalog>   <!-- каталог авторов, книги авторов не описываем, а ссылаемся на них -->   <author_catalog>      <author_book  idref="N1"> С. Граннеман</author_book>      <author_book  idref="N2">К. Уилмер</author_book>      <author_book  idref="N2">А. Хоумер</author_book>      <author_book  idref="N3">Д.Н. Колисниченко</author_book>   </author_catalog> </library>

            4.3 Представление XML документа

На рисунке ниже показан экран Internet Explorer, отображающий разработанный нами XML документ.

Сайт создан в системе uCoz