Определение компонентов (макроопределений)
Компонент (entity) представляет собой определения, содержимое которых может быть повторно использовано в документе . В других языках программирования подобные элементы называются макроопределениями. Создаются DTD- компоненты при помощи инструкции !ENTITY:
<!ENTITY hello ' Мы рады приветствовать Вас!' >
Программа-анализатор, просматривая в первую очередь содержимое области DTD- определений, обработает инструкцию ENTITY, и при дальнейшем разборе документа будет использовать содержимое 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- элемента разработчику требуется определить, данные какого типа могут использоваться в качестве его содержимого. Т.е. если мы определяем элемент <last-modified>10.10.98</last-modified>, то хотим быть уверенными, что в документе в этом месте будет находиться строка, представляющая собой дату, а не число или произвольную последовательность символов. Используя типизацию данных, можно создавать элементы, значения которых могут использоваться, например, в качестве параметров SQL- запросов. Программа клиент в этом случае должна знать, к какому типу данных относится текущее значение элемента и в случае соответствия формирует SQL-запрос.
Если в качестве программы на стороне клиента используется верифицирующий 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.
Схемы данных
Схемы данных (Schemas) являются альтернативным способом создания правил построения XML-документов. По сравнению с DTD, схемы обладают более мощными средствами для определения сложных структур данных, обеспечивают более понятный способ описания грамматики языка, способны легко модернизироваться и расширяться. Безусловным достоинством схем является также тот факт, что они позволяют описывать правила для XML- документа средствами самого же XML.
Однако это не означает, что схемы могут полностью заменить DTD- описания, так как DTD способ определения грамматики языка используется сейчас практическими всеми верифицирующими анализаторами XML и, более того, сами схемы, как обычные XML- элементы, тоже описываются DTD.
Внешне документы схем очень похожи на сами документы XML. В XML схемах документ размечается при помощи специальных элементов, выполняющих в схемах роль инструкций. Эти инструкции составляют набор правил, используя которые, программа-клиент будет делать вывод о том, корректен документ или нет. Схема данных, например, может выглядеть следующем образом:
<schema id="OurSchema">
<elementType id="#title">
<string/>
</elementType>
<elementType id="photo">
<element type="#title">
<attribute name="src"/>
</elementType>
<elementType id="gallery">
<element type="#photo">
</elementType>
</schema>
Если включить приведенные правила внутрь XML- документа, программа-клиент сможет использовать их для проверки, т.е. она сможет определить, что правильным будет являться 1-й фрагмент, а некорректным 2-й фрагмент:
1-й фрагмент
<gallery>
<photo id="1"><title>My computer</title></photo>
<photo id="2"><title>My family</title></photo>
<photo id="3"><title>My dog</title></photo>
</gallery>
2-й фрагмент
<gallery>
<photo id="1"/>
<photo index="2"><title>My family</title></photo>
<photo index="3"><title> My dog </title><dogname>Sharik</dogname></photo>
</gallery>
Область схемы данных
Создавая схемы данных, разработчик документа определяет в документе специальный элемент, <schema>;, внутри которого содержатся описания правил:
<schema id="OurSchema">
<!-- последовательность инструкций -->
</schema>
Если использовать отдельное пространство имен, то полный XML-документ, содержащий в себе схему данных, будет выглядеть следующим образом:
<?XML version='1.0' ?>
<?xml:namespace href="http://www.myserver.ru/schemas/" as="s"/?>
<s:schema id="OurSchema">
<!-- последовательность инструкций -->
</s:schema>
Описание элементов
Для определения класса элемента, к которому в дальнейшем будут применяться инструкции, описывающие его содержимое и структуру, предназначен специальный элемент схемы elementType:
<elementType id="issue">
<descript>Элемент содержит информацию об очередном выпуске журнала</descript>
</elementType>
Название элемента задается атрибутом id . Все дальнейшие инструкции, которые относятся к описываемому классу, определяют его внутреннюю структуру и набор допустимых данных, содержатся внутри блока, заданного тэгами <elementType> и </elementType>.
Как видно из примера, при определении класса элемента, можно также использовать комментарии к нему, которые заключаются в тэги <descript></descript>
Атрибуты элемента
Для того, чтобы в описании элемента определить его атрибуты и описать свойства этих атрибутов мы должны использовать элемент attribute:
<elementType id="photo">
<attribute name="src"/>
<empty/>
</elementType>
В данном примере элементу <photo> определяется атрибут src, значением которого может быть любая последовательность разрешенных символов:
<photo src="0"/>
<photo src="some text">
Подобно DTD, схемы данных позволяют устанавливать ограничения на значения и способ использования атрибутов. Для этого в дескрипторе <attribute> необходимо использовать параметр atttype. Например, если мы хотим указать, что значение атрибута должно использоваться программой-анализатором как уникальный идентификатор, то нам необходимо отределить следующее правило:
<elementType id="bouquet">
<attribute name="id" atttype="ID">
</elementType>
Если же требуется задать список возможных значений атрибута, то пример будет выглядеть следующим образом:
<attribute name="flower" atttype="ENUMERATION" values="red green blue" default="red">
Для приведенных примеров корректным будет являться следующий фрагмент XML-документа:
<bouquet id="0">
<flower color="red">rose</flower>
<flower color="green">leaf</flower>
<flower color="blue">bluet</flower>
</bouquet>
Модель содержимого элемента
Под моделью содержимого в схеме данных понимают описание всех допустимых объектов XML- документа, использование которых внутри данного элемента является корректным. Модель содержимого определяется инструкциями, расположенными внутри блока:
<elementType>.
<elementType id="article">
<attribute name="id" atttype="ID">
<element type="#title">
<string/>
</elementType>
Для этого правила корректным будет являться следующий фрагмент документа:
<article id="0">
<title>Правильный документ</title>
</article>
Вложенные элементы описываются при помощи инструкции element, в которой параметром type указывается класс объекта - ссылка на его определение:
<elementType id="article">
<element type="#title"/>
<element type="#author"/>
</elementType>
Если требуется указать режим использования вложенного элемента, то надо определить параметр occurs:
<elementType id="article">
<element type="#title" occurs="REQUIRED"/>
<element type="#author" occurs="OPTIONAL"/>
<element type="#subject" occurs="ONEORMORE"/>
</elementType>
Возможные значения этого параметра следующие:
- REQUIRED - элемент должен быть обязательно определен;
- OPTIONAL - использование элемента не является обязательным;
- ZEROORMORE - вложенный элемент может встречаться несколько раз или ни разу;
- ONEORMORE - элемент должен встречаться хотя бы один раз.
Кроме элементов, содержимым XML-документа могут являться: обычный текст и области CDATA. Для обозначения типов содержимого текущего элемента в схемах используются следующие инструкции:
- <string> - указывает на то, что содержимым элемента является только свободная текстовая информация (секция PCDATA), например:
<string/>
<elementType id="flower">
<string/>
</elementType>
- <any> - указывает на то, что содержимым элемента должны являться только элементы, без текста, незаключенного ни в один элемент, например:
<any/>
<elementType id="issue">
<any/>
</elementType>
- <mixed> - любое сочетание элементов и текста, например:
<mixed>
<elementType id="contacts">
<mixed/>
</elementType>
- <empty> - пустой элемент.
Группировка элементов
Элемент group используется для того, чтобы задать некоторую последовательность вложенных объектов:
<elementType id="contacts">
<element type="#tel" occurs="ONEORMORE">
<group occurs="OPTIONAL">
<element type="#email">
<element type="#url">
</group>
</elementType>
Группировка объектов позволяет определять сразу группу объектов различных типов, которые могут быть вложены внутри данного объекта. В приведенном примере указано, что внутри объекта типа contacts могут быть включены элементы tel, email, и url, причем атрибутом occurs определено, что элементы в группе являются необязательными. Корректным для таких схем будут являться следующие фрагменты документов:
<contacts>
<tel>12-12-12</tel>
<email>[email protected]</email>
<url>http://www.j.com</url>
</contacts>
...
<contacts>
<tel>12-12-12</tel>
</contacts>
...
<contacts>
<tel>12-12-12</tel>
<email>[email protected]</email>
</contacts>
При помощи атрибута groupOrder можно также задавать режим использования группированных элементов. При установленном значении OR возможно использование не всех элементов группы, а лишь некоторых из них. Если задано значение AND, то оба элемента должны быть включены в обязательном порядке. Например, для следующей группы:
<elementType id="contacts">
<element type="#tel" occurs="ONEORMORE">
<group groupOrder="AND" occurs="OPTIONAL">
<element type="#email">
<element type="#url">
</group>
</elementType>
будут считаться правильными только следующие варианты:
<contacts>
<tel>12-12-12</tel>
<email>[email protected]</email>
<url>http://www.j.com</url>
</contacts>
или
<contacts>
<tel>12-12-12</tel>
</contacts>