- описать, что именно является разметкой;
- описать точно, что означает разметка.
Наиболее известными языками описания схем являются следующие:
- DTD (Document Type Definition) - язык определения типа документов, который первоначально использовался в качестве язык описания структуры SGML-документа.
- XDR (XML Data Reduced) – диалект схемы XML, разработанный Microsoft, который поддерживался в Internet Explorer 4 и 5 версий.
- XML Schema или просто XSD (язык определения схем XML) – рекомендация консорциума W3C с 2001 года.
Рассмотрим подробнее первые два из них. Третий язык описания схем рассматривается в лабораторной работе 11.
DTD схема
Схема DTD предоставляет шаблон разметки документа, в котором указываются наличие , порядок следования и расположение элементов и их атрибутов в документе XML .
В рамках DTD модель содержимого XML документа можно описать следующим образом:
Каждый элемент документа может иметь один из типов:
Содержание | Синтаксис | Комментарий |
---|---|---|
Данные | Содержит только текстовые данные | |
Другие элементы | Содержит только дочерние элементы | |
Смешанное | Содержит комбинацию текстовых данных и дочерних элементов | |
EMPTY | Ничего не содержит | |
ANY | Может содержать текстовые данные или дочерние элементы |
Атрибуты, находящиеся внутри тэгов документа, описываются отдельно с помощью синтаксиса:
При этом атрибут в DTD может иметь один из трех типов:
- Строка
- Маркированные атрибут
- Атрибута с перечислением
Кроме типа атрибута можно также задавать и его модальность:
Рассмотрим в качестве примера описание атрибутов строкового типа для элемента, описывающего некоторое сообщение:
Если этот элемент содержит атрибуты с перечислением , то их описание может выглядеть, например, следующим образом:
Маркированных атрибуты элемента могут быть четырех типов:
И, наконец, в DTD можно использовать следующие индикаторы вхождения последовательностей:
Символ | Пример | Описание |
---|---|---|
, | (a, b, c) | Последовательное использование элементов списка |
| | (a | b | c) | Используется один из членов списка |
date | Используется один и только один элемент | |
? | subject ? | Необязательное использование (0 или 1 раз) |
+ | paragraph+ | Используется один или несколько раз |
* | brother* | Используется ноль или несколько раз |
В качестве примера приведем DTD схему, описывающую структуру электронного почтового ящика:
Используйте для определения структуры XML-документов XML-схемы вместо DTD
XML-схема обладает более мощными возможностями, чем DTD. Для иллюстрации преимуществ использования механизма XML-схем в первых трех листингах сравниваются различные способы представления элементов. В представлена выдержка из XML-документа. В показаны два элемента, объявленные в синтаксисе DTD, а в представлен синтаксис, соответствующий XML-схеме. Обратите внимание, что синтаксис в Листинге 3 подобен синтаксису XML. При использовании схемы, валидирующий парсер может выполнить проверку, является ли элемент InvoiceNo положительным целым числом, и состоит ли ProductID из заданного набора символов (шести цифр и одной буквы от A до Z). Парсер, обрабатывающий DTD-определение, может лишь подтвердить, что данные элементы представляют собой строки.
Листинг 1: Фрагмент XML-документа
Листинг 2: Фрагмент DTD, описывающий элементы из Листинга 1
Листинг 3: Фрагмент XML-схемы, описывающий элементы из Листинга 1
Использование пространств имен в XML-схеме
Ограничения DTD
Несмотря на то, что DTD служат разработчикам SGML и HTML в качестве механизма описания структурированной информации вот уже на протяжении 20-ти лет, DTD обладают некоторыми ограничениями по сравнению с XML-схемами.
Согласно DTD элемент может быть представлен одним из трех способов:
- Текстовая строка
- Текстовая строка, смешанная с другим дочерним элементом
- Набор дочерних элементов
DTD не обладает синтаксисом XML и предлагает лишь ограниченную поддержку для типов и пространств имен.
При совместной работе одна сторона может обрабатывать документы других сторон, и разные стороны могут представлять свои элементы данных по-разному. Более того, в отдельном документе им может потребоваться независимо друг от друга ссылаться на элементы с одинаковым именем, созданные разными сторонами. Использование XML-схемы позволяет различать определения с одним и тем же именем при помощи определения разных пространств имен.
Такая XML-схема определяет набор новых имен, таких как имена элементов, типов, атрибутов, групп атрибутов, чьи определения и объявления описаны в схеме. В имена определяются как InvoiceNo , ProductID и ProductCode .
Имена, определенные в схеме принадлежат так называемому целевому пространству имен . Само по себе пространство имен является фиксированным, произвольным именем, которое должно соответствовать синтаксису URL. К примеру, пространство имен для схемы, представленной в , можно задать следующим образом: http://www.SampleStore.com/Account .
Синтаксис объявления пространства имен иногда может сбить с толку. Объявление начинается с http:// , однако оно не ссылается на файл с описанием схемы. На самом деле, ссылка http://www.SampleStore.com/Account вообще не ведет ни на один файл, а только на назначенное имя.
Определения и объявления в схеме могут ссылаться на имена, которые могут принадлежать другим пространствам имен. В данной статье мы ссылаемся на такие пространства имен как на исходные пространства имен . В каждой схеме может быть определено одно целевое пространство имен и возможно множество исходных пространств имен. Вообще, каждое имя в заданной схеме принадлежит некоему пространству имен. Имена пространства имен могут быть довольно длинными, однако их можно сократить при помощи синтаксиса объявления xmlns в документе XML-схемы. Все эти концепции проиллюстрированы в .
Листинг 4: Целевое и исходное пространства имен
В XML-схеме, представленной с , пространством имен targetNamespace является http://www.SampleStore.com/Account , оно содержит имена InvoiceNo , ProductID и ProductCode . Имена schema , element , simpleType , pattern , string и positive-integer принадлежат исходному пространству имен http://www.w3.org/1999/XMLSchema , которое сокращается как xsd путем объявления xmlns . В псевдониме xsd нет ничего особенного, можно выбрать и другое имя. Для удобства и простоты в оставшейся части статьи мы будем использовать префикс xsd для ссылки на пространство имен http://www.w3.org/1999/XMLSchema , пропуская уточнение xsd в некоторых частях кода. В нашем примере targetNamespace является также одним из исходных пространств имен, так как имя ProductCode используется в определении других имен.
Рисунок 1: Пространства имен для Листинга 4
Листинг 5: Множество исходных пространств имен, импорт пространства имен
Определение элементов
Определением элемента заключается в определении его имени и модели контента. В XML-схеме модель контента элемента определяется его типом. Следовательно, элементы в XML-документе могут иметь только значения, которые подходят типам, определенным в его схеме.
Простые типы
Спецификация XML-схемы определяет несколько простых типов для значений, как показано в Таблице 2 -предопределенные простые типы значений.
Тип элемента может быть простым или комплексным (сложным). Элемент простого типа не может содержать другие элементы или атрибуты. Комплексный тип может создавать эффект встраивания элементов в другие элементы или может ассоциировать атрибуты с элементом. До этого момента мы использовали только примеры с простыми типами, определенными пользователем (см. ProductCode). В спецификацию XML-схемы также включены предопределенные простые типы (см. вставку ). Предопределенный простой тип ограничивает значения по их базовому типу. К примеру, значением предопределенного простого типа ProductCode является подмножество значений базового типа string .
Простые, не вложенные элементы имеют простой тип
Элемент, который не содержит атрибутов или других элементов может быть отнесен к простому типу, предопределенному или определенному пользователем, такому как string , integer , decimal , time , ProductCode и т.п.
Листинг 7: Некоторые простые типы элементов
Элементы с атрибутами должны иметь комплексный тип
Теперь попробуем добавить к простому элементу price из атрибут currency . Вы не сможете этого сделать, так как элемент простого типа не может иметь атрибутов. Если вы хотите добавить атрибут, вам необходимо определить price как элемент комплексного типа. В примере из , мы определяем, так называемый анонимный тип , в котором комплексному типу не дается явного имени. Другими словами, атрибут name элемента complexType не определен.
Листинг 8: Элемент комплексного типа
Элементы, содержащие вложенные элементы должны иметь комплексный тип
В XML-документе в элемент могут быть вложены другие элементы. Это требование выражается напрямую в DTD. XML-схема вместо этого определяет элемент и его тип, который может включать объявления других элементов и атрибутов. Пример приведен в .
Таблица 1: Сравнение комплексных типов данных в DTD и XML-схеме
XML-документ
DTD
XML-схема
Листинг 10: Скрытие BookType как локального типа
Выражение сложных ограничений для элементов
XML-схема предлагает большую гибкость, чем DTD при выражении ограничений для модели контента элементов. На простейшем уровне, таком как в DTD, вы можете ассоциировать с элементом атрибуты, а также указать, что в нем может появляться последовательность из только одного (1), нуля или более (*), или одного или более (+) элементов из заданного набора элементов. В XML-схеме можно выразить дополнительные ограничения, используя для этой цели, к примеру, атрибуты minOccurs и maxOccurs для элемента element и элементы choice , group и all .
Листинг 11: Выражение ограничений для типов элементов
В тег Title является опциональным по отношению к тегу Book (такое же правило можно задать и в DTD). Однако здесь также говорится, что в элементе Book должен быть хотя бы один и не более двух элементов Author . Значением атрибутов minOccurs и maxOccurs тега element по умолчанию является 1. Элемент choice указывает на то, что может появиться только один из указанных дочерних элементов. Другой элемент all определяет, что все дочерние элементы могут появляться только один раз, вместе и в любом порядке, или не появляться совсем. В объявляется, что оба тега Title и Author должны появляться в Book в любом порядке, или не появляться вообще. Подобные ограничения сложно выразить при помощи DTD.
Листинг 12: Указатель того, что у элемента должны быть определены все типы
Подведение итогов
В данном документе мы раскрыли при помощи простых примеров наиболее фундаментальные концепции, необходимые для определения структуры элементов при помощи XML-схемы. Доступно также множество других мощных механизмов:
- XML-схема содержит всестороннюю поддержку для наследования типов, позволяя повторно использовать определенные ранее структуры. Такое использование называют аспектами . Вы можете вывести новые типы, представляющие меньшее подмножество значений других типов, к примеру, для определения подмножества по перечислению, диапазону или по совпадению с шаблоном. В одном из примеров данной статьи тип ProductCode был определен с использованием аспекта pattern . В подтипе также можно добавить для базового типа новые элементы и атрибуты.
- Несколько механизмов, позволяющих контролировать общее определение подтипа или заменять его в определенном документе. К примеру, можно указать, что тип InvoiceType (тип номера инвойса) не может содержать подтипы, то есть никто не сможет определить новую версию InvoiceType . Можно также задать, что в отдельном контексте для типа ProductCode не может быть замещения подтипов.
- Кроме использования подтипов, можно определять эквивалентные типы, то есть значение одного типа может быть замещено значением другого.
- XML-схема обеспечивает механизм для замещения элемента или типа путем объявления их как абстрактных.
- Для большего удобства можно обозначить и задать имена группам атрибутов или элементов. Это позволяет повторно использовать их при последующих обращениях.
- XML-схема предоставляет три элемента – appInfo , documentation и annotation – для использования комментариев, как людьми (documentation) так и приложениями (appInfo)
- Вы можете выразить уникальные ограничения, основывающиеся на определенных атрибутах дочерних элементов.
Дополнительную информацию по XML-схемам можно получить из документаций на сайтах W3C (См. ) и dW XML zone. Теперь, когда спецификация XML-схемы получила подтверждение в качестве кандидата на рекомендацию W3C, вы без сомнения можете использовать ее в полной мере.
Определение типов документа (DTD) декларирует допустимые строительные блоки XML документа. Оно задает структуру документа со списком допустимых элементов и атрибутов.
DTD может декларироваться как в коде самого XML документа, так и во внешнем файле с подключением его к XML документу.
Внутренняя декларация DTD
Если DTD декларируется внутри XML файла, то она должны быть заключена в специальный тег декларации DOCTYPE , который имеет следующий синтаксис:
Пример XML документа с внутренним DTD:
]>
DTD в приведенном примере интерпретируется следующим образом:
- !DOCTYPE note определяет, что корневым элементом документа является note
- !ELEMENT note определяет, что элемент note содержит четыре элемента: to, from, heading, body
- !ELEMENT to определяет, что элемент to должен быть
- !ELEMENT from определяет, что элемент from должен быть типа "#PCDATA"
- !ELEMENT heading определяет, что элемент heading должен быть типа "#PCDATA"
- !ELEMENT body определяет, что элемент body должен быть типа "#PCDATA"
Внешняя декларация DTD
Если DTD декларируется во внешнем файле, то подключение осуществляется следующим образом:
Ниже приводится тот же XML документ, что и ранее, но с внешней декларацией DTD:
А вот что содержится в файле "note.dtd", который декларирует DTD:
Для чего используют DTD?
С DTD каждый ваш XML файл может нести описание своего собственного формата.
С DTD различные, не связанные друг с другом, группы людей могут приходить к соглашению о стандартах взаимно обмениваемых данных.
С DTD вы можете быть уверены, что получаемые из внешних источников данные будут корректными.
Также, вы можете использовать DTD, чтобы проводит проверки корректности своих собственных данных.
В XML- документах DTD определяет набор действительных элементов, идентифицирует элементы, которые могут находиться в других элементах, и определяет действительные атрибуты для каждого из них. Синтаксис DTD весьма своеобразен и от автора-разработчика требуются дополнительные усилия при создании таких документов(сложность DTD является одной из причин того, что использование SGML, требующего определение DTD для любого документа, не получило столь широкого распространения как, например, HTML). Как уже отмечалось, в XML использовать DTD не обязательно - документы, созданные без этих правил, будут правильно обрабатываться программой-анализатором, если они удовлетворяют основным требованиям синтаксиса XML. Однако контроль за типами элементов и корректностью отношений между ними в этом случае будет полностью возлагаться на автора документа. До тех пор, пока грамматика нашего нового языка не описана, его сможем использовать только мы, и для этого мы будем вынуждены применять специально разработанное программное обеспечение, а не универсальные программы-анализаторы..
В DTD для XML используются следующие типы правил: правила для элементов и их атрибутов, описания категорий(макроопределений), описание форматов бинарных данных. Все они описывают основные конструкции языка - элементы, атрибуты, символьные константы внешние файлы бинарных данных.
Для того, чтобы использовать DTD в нашем документе, мы можем или описать его во внешнем файле и при описании DTD просто указать ссылку на этот файл или же непосредственно внутри самого документа выделить область, в которой определить нужные правила. В первом случае в документе указывается имя файла, содержащего DTD- описания:
...
Внутри же документа DTD- декларации включаются следующим образом:
... ... ]> ...
В том случае, если используются одновременно внутренние и внешние описания, то программой-анализатором будут сначала рассматриваться внутренние, т.е. их приоритет выше. При проверке документа XML- процессор в первую очередь ищет DTD внутри документа. Если правила внутри документа не определены и не задан атрибут standalone ="yes" , то программа загрузит указанный внешний файл и правила, находящиеся в нем, будут считаны оттуда. Если же атрибут standalone имеет значение "yes ", то использование внешних DTD описаний будет запрещено.
Определение элемента
Элемент в DTD определяется с помощью дескриптора!ELEMENT , в котором указывается название элемента и структура его содержимого.
Например, для элемента
Ключевое слово ELEMENT указывает, что данной инструкцией будет описываться элемент XML. Внутри этой инструкции задается название элемента(flower) и тип его содержимого.
В определении элемента мы
указываем сначала название
элемента(flower), а затем его модель
содержимого - определяем, какие
другие элементы или типы данных
могут встречаться внутри него. В
данном случае содержимое элемента
flower будет определяться при помощи
специального маркера PCDATA(что
означает parseable character data - любая
информация, с которой может
работать программа-анализатор).
Существует еще две инструкции,
определяющие тип содержимого:
EMPTY,ANY. Первая указывает на то, что
элемент должен быть
пустым(например,
Последовательность дочерних для текущего элемента объектов задается в виде списка разделенных запятыми названий элементов. При этом для того, чтобы указать количество повторений включений этих элементов могут использоваться символы +,*, ? :
В этом примере указывается, что
внутри элемента
Символ * в этом примере указывает на то, что определяемая последовательность внутренних элементов может быть повторена несколько раз или же совсем не использоваться.
Если в определении элемента указывается "смешанное" содержимое, т.е. текстовые данные или набор элементов, то необходимо сначала указать PCDATA, а затем разделенный символом "|" список элементов.
Пример корректного XML- документа:
]>
...
Определение атрибутов
Списки атрибутов элемента
определяются с помощью ключевого
слова!ATTLIST
. Внутри него
задаются названия атрибутов, типы
их значений и дополнительные
параметры. Например, для элемента
В данном примере для элемента article определяются три атрибута: id, about и type , которые имеют типы ID(идентификатор), CDATA и список возможных значений соответственно. Всего существует шесть возможных типов значений атрибута:
- CDATA - содержимым документа могут быть любые символьные данные
- ID - определяет уникальный идентификатор элемента в документе
- IDREF(IDREFS)- указывает, что значением атрибута должно выступать название(или несколько таких названий, разделенных пробелами во втором случае) уникального идентификатора определенного в этом документе элемента
- ENTITY(ENTITIES) - значение атрибута должно быть названием(или списком названий, если используется ENTITIES) компонента (макроопределения), определенного в документе
- NMTOKEN (NMTOKENS) - содержимым элемента может быть только одно отдельное слово(т.е. этот параметр является ограниченным вариантом CDATA)
- Список допустимых значений - определяется список значений, которые может иметь данный атрибут.
Также в определении атрибута можно использовать следующие параметры:
- #REQUIRED - определяет обязательный атрибут, который должен быть задан во всех элементах данного типа
- #IMPLIED - атрибут не является обязательным
- #FIXED "значение" - указывает, что атрибут должен иметь только указанное значение, однако само определение атрибута не является обязательным, но в процессе разбора его значение в любом случае будет передано программе-анализатору
- Значение - задает значение атрибута по умолчанию
Определение компонентов(макроопределений)
Компонент (entity) представляет собой определения, содержимое которых может быть повторно использовано в документе. В других языках программирования подобные элементы называются макроопределениями. Создаются DTD- компоненты при помощи инструкции!ENTITY:
Программа-анализатор, просматривая в первую очередь содержимое области DTD- определений, обработает эту инструкцию и при дальнейшем разборе документа будет использовать содержимое DTD- компонента в том месте, где будет встречаться его название. Т.е. теперь в документе мы можем использовать выражение &hello; , которое будет заменено на строчку "Мы рады приветствовать Вас"
В общем случае, внутри DTD можно задать три типа макроопределений:
Внутренние макроопределения - предназначены для определения строковой константы, с их помощью можно организовывать ссылки на часто изменяемую информацию, делая документ более читабельным. Внутренние компоненты включаются в документ при помощи амперсанта &
В XML существует пять предустановленных внутренних символьных констант:
- < - символ "<"
- > - символ ">"
- & - символ "&"
- " - символ апострофа """
- " - символ двойной кавычки """
Внешние макроопределения - указывают на содержимое внешнего файла, причем этим содержимым могут быть как текстовые, так и двоичные данные. В первом случае в месте использования макроса будут вставлены текстовые строки, во втором - бинарные данные, которые анализатором не рассматриваются и используются внешними программами
Макроопределения правил - макроопределения параметров могут использоваться только внутри области DTD и обозначаются специальным символом %, вставляемым перед названием макроса. При этом содержимое компонента будет помещено непосредственно в текст DTD- правила
Например, для следующего фрагмента документа:
можно использовать более короткую форму записи:
Макроопределения часто используются для описания параметров в правилах атрибутов. В этом случае появляется возможность использовать одинаковые определения атрибутов для различных элементов:
Типизация данных
Довольно часто при создании XML-
элемента разработчику требуется
определить, данные какого типа
могут использоваться в качестве
его содержимого. Т.е. если мы
определяем элемент
Если в качестве программы на стороне клиента используется верифицирующий XML-процессор, то информацию о типе можно передавать при помощи специально созданного для этого атрибута элемента, имеющего соответствующее DTD- определение. В процессе разбора программа-анализатор передаст значение этого атрибута клиентскому приложению, которое сможет использовать эту информацию должным образом. Например, чтобы указать, что содержимое элемента должно быть длинным целым, можно использовать следующее DTD- определение:
Задав атрибуту значение по умолчанию LONG и определив его как FIXED, мы позволили тем самым программе-клиенту получить необходимую информацию о типе содержимого данного элемента, и теперь она может самостоятельно определить соответствие типа этого содержимого указанному в DTD- определении.
Вот пример XML- документа, в котором определяются и используются несколько элементов с различными типами данных:
...
Как видно из примера, механизм создания элементов документа при этом нисколько не изменился. Все необходимая для проверки типов данных информация заложена в определения элементов внутри блока DTD.
В заключении хотелось бы отметить, что DTD предоставляет нам весьма удобный механизм осуществления контроля за содержимым документа. На сегодняшний день, практически все программы просмотра документов Интернет используют DTD-правила. Однако это далеко не единственный способ проверки корректности документа. В настоящий момент в W3 консорциуме находится на рассмотрении новый стандарт языка описания структуры документов, называемый схемами данных. Следующий раздел посвящен работе с ними.