Создание действительных (valid) XML-документов. Определение типа документа (DTD)
Любой XML-документ должен отвечать минимальным требованиям по составлению, т.е. быть корректно сформированным. Если документ содержит ошибки, он не может считаться XML-документом.
Корректно сформированный XML-документ также может быть действительным (valid). Действительным называется корректно сформированный (well-formed) документ, отвечающий двум дополнительным требованиям2):
- Пролог документа должен содержать специальное объявление типа документа, которое включает определение типа документа (Data Type Definition, DTD), задающее структуру документа.
- Корневой элемент должен отвечать структуре, заданной в DTD.
Использование критерия действительности необходимо для включения XML-документа в группу схожих документов, отвечающих определенной структуре или набору стандартов. Достаточно один раз выработать схему DTD и затем просто подключать ее к создаваемым документам. Стандарт XML определяет DTD как "грамматику для определенного класса документов".
Объявление типа документа представляет собой блок XML-разметки, который располагается в любом месте пролога корректно сформированного документа. Оно имеет следующую обобщенную форму записи:
<!DOCTYPE Название_корневого_элемента DTD>
DTD представляет собой определение типа документа. Оно состоит из символа левой квадратной скобки ([), после которой следует ряд объявлений разметки, заканчивающихся правой квадратной скобкой (]). Объявления разметки описывают логическую структуру документа, т.е. задают элементы документа, атрибуты и другие компоненты. Действительный XML-документ, содержащий DTD с единственным объявлением разметки, которое определяет один тип элемента в документе, TABLE, выглядит так (рис. 10.15).
Рис. 10.15. Простейший документ с DTD
В этом примере DTD документа указывает, что он может содержать только элементы типа TABLE (это единственный заданный тип элемента) и что элемент TABLE может иметь любое допустимое для данного типа содержимое (ключевое слово ANY).
DTD может содержать различные типы объявлений разметки: объявления типов документов, объявления типов атрибутов, инструкции по обработке и другие.
Объявление типа элемента имеет следующую обобщенную форму:
<!ELEMENT Название_элемента описание_содержимого>
Некоторые возможные описания содержимого приведены в таблице 10.5.
1 | <!ELEMENT Название_элемента (#PCDATA)> | Элемент TABLE может содержать только символьные данные, дочерние элементы не допускаются |
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE TABLE [<!ELEMENT TABLE (#PCDATA)>] > <TABLE>Простейший документ</TABLE> | <?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE TABLE [<!ELEMENT TABLE (#PCDATA)>] > <TABLE> <TOUR></TOUR> Простейший документ </TABLE> | |
2 | <!ELEMENT Название_элемента ANY> | Элемент TABLE может содержать любые данные. Объявлять тип элемента в документе можно только один раз. |
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE TABLE [<!ELEMENT TABLE ANY>] > <TABLE> <TOUR></TOUR> Простейший документ </TABLE> | <?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE TABLE [<!ELEMENT TABLE ANY>] > [<!ELEMENT TABLE (#PCDATA)>] > <TABLE> <TOUR></TOUR> Простейший документ </TABLE> | |
3 | <!ELEMENT Название_элемента (Название_дочернего_элемента)+> | Элемент TABLE может содержать один или несколько элементов TOUR |
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE TABLE [<!ELEMENT TABLE (TOUR)+>] > <TABLE> <TOUR>Кипр</TOUR> <TOUR>Греция</TOUR> <TOUR>Таиланд</TOUR> <TOUR>Италия</TOUR> </TABLE> | ||
4 | <!ELEMENT Название_элемента EMPTY> | Элемент TABLE должен быть пустым, т.е. не иметь содержимого |
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE TABLE [<!ELEMENT TABLE EMPTY>] > <TABLE> </TABLE> | <?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE TABLE [<!ELEMENT TABLE EMPTY>] > <TABLE> Простейший документ </TABLE> |
При создании документа XMLTour. xml мы определили элемент TOUR, который содержит дочерние элементы в следующей последовательности: IDTOUR, NAME, PRICE и INFORMATION. Далее, при заполнении списка туров для нас важно осуществлять проверку расположения элементов - дочерние элементы должны располагаться только так. В таблице 10.6 рассмотрены некоторые типичные примеры определения расположения дочерних элементов.
1 | <!ELEMENT Название_элемента (Название_первого_дочернего_элемента, название_второго_дочернего_элемента, название_третьего_дочернего_элемента,:, название_n-ного_дочернего_элемента)> | Последовательная форма модели содержимого указывает, что элемент должен иметь заданную последовательность дочерних элементов. Имена типов дочерних элементов отделяются запятыми. Пропуск дочернего элемента или использование одного и того же типа дочернего элемента более одного раза также недопустимо |
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE TOUR [ <!ELEMENT TOUR (IDTOUR, NAME, PRICE, INFORMATION)> <!ELEMENT IDTOUR (#PCDATA)> <!ELEMENT NAME (#PCDATA)> <!ELEMENT PRICE (#PCDATA)> <!ELEMENT INFORMATION (#PCDATA)> ] > <TOUR> <IDTOUR>1</IDTOUR> <NAME>Кипр</NAME> <PRICE>25 000,00р. </PRICE> <INFORMATION>В стоимость двух взрослых путевок входит цена одной детской (до 7лет)</INFORMATION> </TOUR> | <?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE TOUR [ <!ELEMENT TOUR (IDTOUR, NAME, PRICE, INFORMATION)> <!ELEMENT IDTOUR (#PCDATA)> <!ELEMENT NAME (#PCDATA)> <!ELEMENT PRICE (#PCDATA)> <!ELEMENT INFORMATION (#PCDATA)> ] > <TOUR> <NAME>Кипр</NAME> <IDTOUR>1</IDTOUR> <PRICE>25 000,00р. </PRICE> <INFORMATION>В стоимость двух взрослых путевок входит цена одной детской (до 7лет)</INFORMATION> </TOUR> | |
2 | <!ELEMENT Название_элемента (Название_первого_дочернего_элемента | название_второго_дочернего_элемента | название_третьего_дочернего_элемента |:| название_n-ного_дочернего_элемента)> | Выборочная форма модели содержимого указывает, что элемент может иметь один любой из серии допустимых дочерних элементов, разделяемых символом "|" |
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE TOUR [ <!ELEMENT TOUR (IDTOUR | NAME | PRICE | INFORMATION)> <!ELEMENT IDTOUR (#PCDATA)> <!ELEMENT NAME (#PCDATA)> <!ELEMENT PRICE (#PCDATA)> <!ELEMENT INFORMATION (#PCDATA)> ] > Правильные варианты:
| <?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE TOUR [ <!ELEMENT TOUR (IDTOUR | NAME | PRICE | INFORMATION)> <!ELEMENT IDTOUR (#PCDATA)> <!ELEMENT NAME (#PCDATA)> <!ELEMENT PRICE (#PCDATA)> <!ELEMENT INFORMATION (#PCDATA)> ] > Неправильные варианты:
|
Рассмотренные модели содержимого можно дополнять следующими знаками:
+ - один или несколько элементов;
* - ни одного или несколько элементов;
? - ни одного или один элемент.
Следующее объявление означает, что документ может содержать один или несколько элементов NAME и что элемент INFORMATION может не существовать или быть в единственном экземпляре:
... <!ELEMENT TOUR (IDTOUR, NAME+, PRICE, INFORMATION?)> ... <TOUR> <IDTOUR>1</IDTOUR> <NAME>Кипр</NAME> <NAME>Греция(включая Кипр)</NAME> <PRICE>25 000,00р. </PRICE> </TOUR>
Другое объявление означает, что документ может содержать ни одного или несколько элементов IDTOUR, либо элемент NAME, либо элемент PRICE, либо ни одного или один элемент INFORMATION:
... <!ELEMENT TOUR (IDTOUR* | NAME| PRICE | INFORMATION?)> ...
Соответствующие правильные три варианта выглядят следующим образом:
<TOUR> <IDTOUR>1</IDTOUR> <IDTOUR>2</IDTOUR> </TOUR>
<TOUR> <NAME>Кипр</NAME> </TOUR>
<TOUR> </TOUR>
Указанные модели и символы поддерживают сложные образования, образуемые вложением последовательной модели содержимого в выборочную, и наоборот. Примером такого сложного образования может служить следующее объявление:
<!DOCTYPE TOUR [ <!ELEMENT TOUR (IDTOUR, NAME, (PRICE_EURO | PRICE_DOLLAR | PRICE_RUB) )> <!ELEMENT IDTOUR (#PCDATA)> <!ELEMENT NAME (#PCDATA)> <!ELEMENT PRICE_EURO (#PCDATA)> <!ELEMENT PRICE_DOLLAR (#PCDATA)> <!ELEMENT PRICE_RUB (#PCDATA)> ] >
Для него будут верными следующие варианты корневого элемента:
<TOUR> <IDTOUR>1</IDTOUR> <NAME>Кипр</NAME> <PRICE_RUB>25 000,00р. </PRICE_RUB> </TOUR>
<TOUR> <IDTOUR>1</IDTOUR> <NAME>Кипр</NAME> <PRICE_DOLLAR>1000$. </PRICE_DOLLAR> </TOUR>
<TOUR> <IDTOUR>1</IDTOUR> <NAME>Кипр</NAME> <PRICE_EURO>760 _. </PRICE_EURO> </TOUR>