XML technologies: XML, DTD, XML Schema

Автор: Талисов М.Е. Copyright © 2007. Все права защищены.
В данном руководстве рассматриваются различные XML-технологии, такие как: XML, DTD, XMLSchema на простых примерах.
Дата создания: 02.03.07.

Cодержание

  1. 1 Краткое описание технологии XML
    1. 1.1 Комментарии
    2. 1.2 Инструкции обработки
    3. 1.3 Секции CDATA
    4. 1.4 Ссылки на сущности и символы
    5. 1.5 XML-объявления и текстовые объявления
    6. 1.6 DTD (Document Type Declaration)
    7. 1.7 Обобщенная структура XML-документа
  2. 2 DTD
    1. 2.1 Краткое описание языка DTD
    2. 2.2 Пример DTD-описания
  3. 3 XML Schema
    1. 3.1 Пространство имен XML
    2. 3.2 Краткое описание XML Schema
    3. 3.3 Пример XML-схемы

1 Краткое описание технологии XML

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

<имя_элемента> тело_элемента </имя_элемента>

В теле элемента может быть расположен текст, вложенные элементы. Тело элемента может быть пустым. В этом случае элемент можно записывать двумя разными способами:

<имя_элемента></имя_элемента>

или так:

<имя_элемента/>

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

<имя_элемента атрибут_1 = "значение_1" атрибут_2 = "значение_2" ... > тело_элемента </имя_элемента>

Определиться, где хранить информацию, связанную с элементом ( во вложенных элементах или атрибутах), просто: если информация простая, т.е. ее можно представить в виде строки или числа, то ее можно указать атрибутом (например цвет, год выпуска автомобиля). Эту информацию конечно можно указать и в виде вложенного в элемент "автомобиль" элемента "цвет" или "дата выпуска", но в данном случае логичнее будет указать ее в атрибутах, исходя из предметной области, т.к. цвет и дата выпуска не вложены физически в автомобиль, это просто дополнительная информация о нем. А вот в качестве вложенных элементов автомобиля можно указать например двигатель (с другими вложенными элементами) и т.п.

У XML-документа может быть только один корневой элемент. Таким образом XML-документ представляет собой дерево элементов с атрибутами.

Кроме элементов спецификация XML определяет еще несколько конструкций, которые могут использоваться при формировании XML-документа:

  • Ссылки на сущности (entity references)
  • Ссылки на символы (character references)
  • Комментарии (comments)
  • Секции CDATA (CDATA sections)
  • Объявления типа документа (document type declarations)
  • Инструкции обработки (processing instructions)
  • XML-объявления (XML declarations)
  • Объявления текста (text declarations)

которые совместно с открывающими тэгами (start tags), закрывающими тэгами (end tags) формируют разметку (mark up), которая позволяет представить текст в высокоструктурированном виде. В формировании разметки также участвуют тэги пустых элементов (empty-elements tags).

XML-документы, удовлетворяющие общим требованиям спецификации XML, называются well-formed. Если документы удовлетворяют еще и заданным спецификацией средствами ограничений, определяемыми предметной областью, то он называется valid.

Для описания ограничений на содержание XML-документа в соответствии с ограничениями предметной области существует ряд технологий:

  • DTD (Document Type Declaration)
  • W3C XMLSchema

Рассмотрим различные виды разметки:

1.1 Комментарии

<!-- текст комментария -->

Предназначен для внедрения в XML-документ информации, которая не считается частью данных, переданных в составе XML-документа. XML-анализатор может включать, а может и не включать комментарии в результате анализа – это зависит от анализатора. В тексте комментария нельзя использовать --.

1.2 Инструкции обработки

<? имя_инструкции данные ?>

Имя_инструкции должно отличаться от имени XML в любом сочетании регистра символов. Данные – необязательно, но если есть – нельзя использовать ?>. Инструкции обработки внедряются в XML-документ для того, чтобы сообщить прикладной программе дополнительные сведения о том, как обрабатывать XML-документ. XML-анализатор обязан включать все инструкции обработки в результате анализа.

1.3 Секции CDATA

<![CDATA[ текст ]]>

При этом текст не должен содержать ]]>. Секции CDATA используются для оформления фрагментов текста, которые содержат множество символов, запрещенных спецификацией для употребления в литеральной форме в составе текста. Внутри секции CDATA они могут быть в литеральной форме.

Спецификация XML запрещает использовать символы & и < в их литеральной форме везде, кроме разделителей разметки (ссылки на сущности и символы, а также тэги) или внутри комментариев, инструкций обработки и секции CDATA. Во всех остальных случаях эти символы должны заменяться на встроенные esc-последовательности. Например, в теле элемента или в значении атрибута.

1.4 Ссылки на сущности и символы

Ссылки на сущности и символы используются для замены фрагментов текста или одного символа соответствующей esc-последовательностью. Ссылки на символы оформляются так: &#десятичный код; либо &#xшестнадцатеричный код;. Указанный десятичный или шестнадцатеричный код ссылается на UNICODE-символ.

Ссылки на сущности оформляются по-разному, в зависимости от того, где они используются. Если ссылка на сущность используется внутри XML-документа, но за пределами DTD, то: &имя сущности;. Если используется в составе DTD-описания, то: %имя сущности;. В любом случае имя сущности должно быть определено в составе DTD-описания и оно не должно быть рекурсивным. В результате анализа XML-анализатор заменяет вхождения ссылки на соответствующий символ или текст.

1.5 XML-объявления и текстовые объявления

XML-объявления, текстовые объявления указывают, что документ является XML-документом, а не каким-то другим. При этом XML-объявление не обязательно. Текстовые объявления указывается в тех XML-документах, которые включаются по ссылке в другие XML-документы. Например, XML-объявление указывается в тех документах, которые не включены в другие XML-документы.

XML-объявления и текстовые объявления в общем случае выглядят одинаково:

<? xml version = "номер версии" encoding = "имя_кодировки_документа" ?>

Здесь, в XML-объявлении, предложение encoding – необязательно, а version – обязательно. В текстовом объявлении оба предложения - необязательны. Если не указана кодировка, используется utf-8 (UNICODE). Если не указывается версия, то используется 1.0.

1.6 DTD (Document Type Declaration)

Ограничения на структуру XML-документов, специфичные для той или иной предметной области, могут быть описаны формально одним из двух способов: DTD или W3C XMLSchema.

Язык DTD определен в составе спецификации XML, является простым языком с довольно ограниченными возможностями. XMLSchema описывается на XML-языках, которые определяются отдельными спецификациями. Комитетом W3C в качестве международного стандарта был утвержден язык описания XMLSchema.

DTD-описания могут включаться непосредственно в состав XML-документа, а могут оформляться в отдельном файле. В последнем случае в XML-документ может быть внедрена ссылка на DTD-описание. Допускается также одновременно внедрить ссылку на DTD и само DTD-описание. В этом случае непосредственное присутствие DTD-описания имеет приоритет над ссылкой.

Для внедрения DTD-описания непосредственно или по ссылке используется document type declaration:

по ссылке:

<! DOCTYPE имя_корневого_элемента ссылка >

непосредственно:

<! DOCTYPE имя_корневого_элемента [ DTD-описание ] >

по ссылке и непосредственно:

<! DOCTYPE имя_корневого_элемента ссылка [ DTD-описание ] >

1.7 Обобщенная структура XML-документа

В общем, документ можно представить из последовательности трех частей: пролог, корневой элемент, разное. Пролог включает последовательно необязательное XML-объявление, комментарии и инструкции обработки. Среди них может присутствовать одно объявление типа документ. Корневой элемент содержит структурные данные и может содержать текст, вложенные элементы, комментарии, секции CDATA, инструкции обработки. После корневого элемента могут идти комментарии и инструкции обработки.

Любые элементы разметки могут оформляться пробельным материалом (white space): пробел (%#x20;), табуляция (&#x9), перевод каретки (&#xD), возврат строки (&#xA).

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

Обработка символов конца строки ведется следующим образом: любая последовательная пара символов &#xD; &#xA; а также &#xD; без &#xA преобразуется в &#xA.

2 DTD

2.1 Краткое описание языка DTD

Язык DTD (Document Type Declaration) представляет собой последовательность объявлений и ссылок на параметризованные сущности (parameter entity reference). Объявления могут содержать: объявления элементов, атрибутов, сущностей, нотаций, а также инструкции обработки и комментарии.

Рассмотрим последовательно элементы языка DTD:

Элементы

<!ELEMENT имя_элемента спецификация_тела>

Спецификация тела может указывать, что: элемент пустой (EMPTY), ограничение на тело отсутствует (ANY), либо задавать некую модель тела. Модель задается с использованием конструкций последовательности и выбора, с которыми можно использовать модификаторы повторения: ? – необязательное присутствие элемента; + - элемент присутствует один или более раз последовательно; * - элемент присутствует 0 или более раз последовательно. Последовательность задается с помощью конструкции: (имя_элемента, имя_элемента, ...). Выбор: (имя_элемента|имя_элемента|...). Конструкции повтора и выбора можно комбинировать произвольным образом. Чтобы указать, что в теле элемента может быть только текст, указывается #PCDATA. Чтобы указать, что в теле элемента могут произвольным образом смешиваться текст и элементы, используют: (#PCDATA|имя_элемента|имя_элемента|...)*.

Атрибуты

Список атрибутов для элемента можно описать так:

<!ATTLIST имя_элемента список_определений>

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

Встроенные типы:

  • CDATA – значением атрибута является произвольный текст;
  • ID – указывает, что значением атрибута является некоторое имя, которое в пределах документа уникально (среди любых элементов с атрибутами этого типа). У любого элемента может быть атрибут типа ID, но только один;
  • IDREF – значением атрибута является значение атрибута типа ID какого-то другого элемента;
  • IDREFS – представляет список значений типа IDREF, элементы списка разделяются пробелами;
  • ENTITY – значением атрибута является имя неанализируемой сущности (unparsed entity), которая описана в DTD;
  • ENTITIES – значениями является список значений типа ENTITY, которые разделяются между собой пробелами;
  • NMTOKEN – тип указывает, что значением атрибута является строка, состоящая из букв, цифр и символов ".", "-", "_", ":";
  • NMTOKENS значение – список значений типа NMTOKEN, разделенных пробелом.

Перечислимые типы задают список возможных значений атрибута. Задаются одним из двух способов:

  1. (имя|имя|...);
  2. NOTATION (имя_нотации|имя_нотации|...). В этом случае каждое из имен должно быть описано как нотация в DTD.

Ограничение: у элемента может быть не более одного атрибута типа NOTATION, а у элементов, объявленных как EMPTY, атрибутов типа NOTATION быть не может вовсе. Атрибуты типа NOTATION используются для связывания с элементами некоторого публичного или системного идентификатора, который может быть использован приложением для идентификации тела элемента.

Умолчания описываются следующим образом:

  • #REQUIRED – атрибут обязателен;
  • #IMPLIED – значение по умолчанию не указано и атрибут необязателен;
  • #FIXED – атрибут обязательно должен быть указан с этим значением (имя_атрибута тип_атрибута #FIXED значение);

Атрибут типа ID должен быть описан как #REQUIRED или #IMPLIED. Заданное значение по умолчанию должно соответствовать типу атрибута. Значение по умолчанию указывается в одинарных или двойных кавычках.

Значения атрибутов в документе при анализе подвергаются процедуре нормализации, которая выполняется так:

  1. выполняется обработка символов конца строки;
  2. выполняется замена ссылок на символы символами;
  3. каждая ссылка на сущность обрабатывается рекурсивно до тех пор, пока не будет вычислен замещающий ее текст;
  4. любой пробельный символ заменяется на пробел.
  5. если тип атрибута не CDATA, то значение атрибута далее обрабатывается так: удаляются все ведущие и концевые пробелы, а все последовательности пробелов заменяются на один пробел.

Сущности и ссылки на них

Сущности бывают двух типов: общие (general) и параметризованные (parameter). Сущности каждого вида делятся на внутренние (internal) и внешние (external).

General external entities дополнительно делятся на анализируемые (parsed) и неанализируемые (unparsed). Различия между общими и параметризованными сущностями заключаются в том, что ссылка на общую сущность может присутствовать в XML-документе и в DTD, а ссылка на параметризованную сущность – внутри DTD-описания.

Для внутренних сущностей замещающий текст указывается непосредственно при описании сущности. Для внешних - указывается ссылка на ресурс, который содержит замещающий текст. Различия между parsed и unparsed:

  1. parsed включается в состав XML-документа и участвует при формировании результата анализа;
  2. unparsed ссылаются на внешние ресурсы произвольного содержания. Обработка таких ресурсов выполняется не XML-анализатором, а приложением.

Общие сущности:

<!ENTITY имя_сущности спецификация_сущности>

Спецификация сущности может задаваться значением сущности в одинарных или двойных кавычках, может содержать ссылки на символы, а также общие и параметризованные сущности. Спецификация может указывать ссылку на ресурс: SYSTEM uri, либо PUBLIC публичный_идентификатор uri. Uri содержит ссылку на физический ресурс (в том или ином формате (URI, URM)), который будет использован для извлечения значения сущности.

Публичный идентификатор – некий идентификатор, который принято составлять следующим образом: -//W3C//язык_описания имя_проекта//язык. Например, для HTML документа: -//W3C//DTD HTML 4.01//EN

После ссылки может идти указание нотации в виде NDATA – имя нотации. Если указание нотации присутствует, то эта сущность general external unparsed, иначе general external parsed. При этом используемое здесь имя нотации должно быть объявлено. Если значение сущности указано при объявлении, то она general external.

Параметризованные сущности:

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

  1. перед именем сущности ставится %;
  2. при описании external сущностей нельзя использовать указание нотации, так как все параметризованные сущности считаются parsed.

Замечание: ссылка на DTD в document type declaration оформляется по тем же правилам, что и ссылка на значение внешней сущности.

Ссылки на сущности используются с определенными ограничениями:

  1. имя сущности должно быть описано;
  2. сущность должна быть parsed;
  3. имена неанализируемых сущностей могут быть использованы только как значения атрибутов типа ENTITY и ENTITIES;
  4. ссылки на параметризованные сущности не должны появляться за пределами DTD;
  5. анализируемые сущности не должны содержать ссылок на самих себя;
  6. внешние анализируемые сущности должны начинаться с text declaration.

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

Нотации

<!NOTATION имя_нотации ссылка>

Объявление нотаций вводит имена, которые могут использоваться при описании общих внешних неанализируемых сущностей или тела элемента, содержащего атрибут типа NOTATION. Обработка такого рода содержимого должна выполняться приложением. Ссылка может содержать системный идентификатор: SYSTEM URL, либо PUBLIC публичный_идентификатор, либо то и другое вместе: PUBLIC публичный_идентификатор URL.

2.2 Пример DTD-описания

Здесь рассматривается пример DTD, описывающего предметную облать "Компьютерный магазин". Краткое описание данной предметной области: имеются две главные сущности - это проданный системный блок (chassis) и сотрудник (employee). При этом имеется информация о том, какой сотрудник продал данный системный блок. Корневым элементом документа является элемент shop.

Элемент chassis имеет атрибуты: идентификатор (id), дату (dateofsale), цену продажи (price) и атрибут (whosold), указывающий идентификатор сотрудника, продавшего системный блок. У системного блока указана его конфигурация: корпус (case), материнская плата (motherboard), процессор (cpu), оперативная память (ram), жесткий диск (hdd), оптический привод (diskdrive) и видеокарта (videocard). В системном блоке должна быть только одна материнская плата, один процессор и одна память. В системном блоке может быть один и более жестких дисков (в XML-схеме количество ЖД и оптических приводов будет ограничено четырьмя штуками), оптических приводов может быть несколько, а может и не быть совсем, также не обязательна видеокарта (она может быть встроена в материнскую плату). Корпус системного блока имеет следующие атрибуты: цвет, тип и название. Также в нем должен быть указан дочерний элемент epu (блок питания), указывающим его мощность в ваттах, с атрибутом turbo. Материнская включает следующие элементы: название (title), модель (model) и тип чипсета (chipset), кроме того, она может содержать и обычный текст. Пустой элемент cpu имеет следующие атрибуты: модель, частота ядра и часта шины, связывающей процессор с ОЗУ. Элемент ОЗУ имеет только один атрибут – объем памяти (size). Жесткий диск имеет атрибуты модель и ёмкость. Оптический привод имеет атрибуты тип, модель и скорость. Видеокарта имеет атрибуты тип и модель.

Кроме этого, в корневом элементе могут быть указаны контакты магазина (contactsShop) и изображение его логотипа (image). Контакты состоят из адреса, телефона, факса и адреса электронной почты, а также произвольного текста. Элемент image имеет атрибут src, указывающий ссылку на файл с изображением логотипа, и alt - текст. В корневом элементе также указывается элемент emplist, который содержит список сотрудников магазина (employee). У элемента employee указываются элементы: fio (ФИО), post (должность), age (возраст) и contactsEmployee (контакты сотрудника). Также у него есть атрибут - идентификатор.

DTD-описание выполнено в отдельном внешнем файле. Документ-пример содержит ссылку на DTD-описание: <!DOCTYPE shop SYSTEM "MyShop.dtd">.

DTD-описание демонстрирует использование конструкций описания элементов с вложенными элементами и применением следования, альтернативы, необязательности и повторяемости этих вложенных элементов: <!ELEMENT shop (contactsShop, chassis+, image?, emplist)>.

DTD-описание демонстрирует использование конструкций описания атрибутов, как обязательных, так и необязательных, в том числе со значением по умолчанию для атрибутов следующих типов: ID, IDREF или IDREFS, CDATA, а также одного из перечисляемых типов:

<!ATTLIST case %color; "white" type (atx|matx) "atx" title CDATA #REQUIRED >

Параметризованная и обычная сущности, и ссылки на них в DTD-описании и документе-примере:

<!ENTITY % idattr "id ID #IMPLIED"> <!ENTITY address1 "ул. Мира, д.15"> <!ATTLIST chassis %idattr; dateofsale CDATA #REQUIRED price CDATA #REQUIRED whosold IDREF #REQUIRED > <contactsShop> Наш адрес: <address>&address1;</address>, телефоны: <phone>8(905)613-90-06</phone>, <phone>785-45-22</phone>, факс:<fax>65765765</fax>, электронный ящик:<email>mymail@mail.ru</email> </contactsShop>

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

<!ELEMENT image EMPTY> <!ATTLIST image src ENTITY #IMPLIED alt CDATA #IMPLIED > <!NOTATION gif87a PUBLIC "image/gif"> <!ENTITY logotype SYSTEM "/logo.gif" NDATA gif87a>

Полный листинг DTD-описания:

<!--Корневой элемент - магазин--> <!ELEMENT shop (contactsShop, chassis+, image?, emplist)> <!--Логотип магазина--> <!ELEMENT image EMPTY> <!ATTLIST image src ENTITY #IMPLIED alt CDATA #IMPLIED > <!--Параметризованные сущности--> <!ENTITY % idattr "id ID #IMPLIED"> <!ENTITY % color "color (white|silver|black|red|blue|green)"> <!--Обычные сущности--> <!ENTITY address1 "ул. Мира, д.15"> <!ENTITY address2 "пр. Строителей, д.3"> <!--Определение нотации--> <!NOTATION gif87a PUBLIC "image/gif"> <!--Ссылки на внешние неанализируемые сущности--> <!ENTITY logotype SYSTEM "/logo.gif" NDATA gif87a> <!--Контакты--> <!ELEMENT address (#PCDATA)> <!ELEMENT phone (#PCDATA)> <!ELEMENT fax (#PCDATA)> <!ELEMENT email (#PCDATA)> <!--Контакты магазина--> <!ELEMENT contactsShop (#PCDATA|address|phone|fax|email)*> <!--Контакты сотрудника--> <!ELEMENT contactsEmployee (#PCDATA|address|phone|email)*> <!--Блок питания--> <!ELEMENT epu (#PCDATA)> <!ATTLIST epu turbo CDATA #REQUIRED> <!--Корпус системного блока--> <!ELEMENT case (epu)> <!ATTLIST case %color; "white" type (atx|matx) "atx" title CDATA #REQUIRED > <!--Материнская плата--> <!ELEMENT title (#PCDATA)> <!ELEMENT model (#PCDATA)> <!ELEMENT chipset (#PCDATA)> <!ELEMENT motherboard (#PCDATA|title|model|chipset)*> <!--Процессор--> <!ELEMENT cpu EMPTY> <!ATTLIST cpu model (amd|pentium) "pentium" frequency CDATA #REQUIRED fsb CDATA #IMPLIED > <!--Оперативная память--> <!ELEMENT ram EMPTY> <!ATTLIST ram size CDATA #REQUIRED> <!--Жесткий диск--> <!ELEMENT hdd EMPTY> <!ATTLIST hdd model CDATA #REQUIRED size CDATA #REQUIRED > <!--Оптический привод--> <!ELEMENT diskdrive EMPTY> <!ATTLIST diskdrive type (cdrom|cdrw|dvdrom|cdrwdvdrom|cdrwdvdrw) "cdrom" model CDATA #REQUIRED speed CDATA #IMPLIED > <!--Видеокарта--> <!ELEMENT videocard EMPTY> <!ATTLIST videocard type (nvidia|ati) "nvidia" model CDATA #REQUIRED > <!--Системный блок--> <!ELEMENT chassis (case, motherboard, cpu, ram, hdd+, diskdrive*, videocard?)> <!ATTLIST chassis %idattr; dateofsale CDATA #REQUIRED price CDATA #REQUIRED whosold IDREF #REQUIRED > <!--Сотрудник--> <!ELEMENT fio (#PCDATA)> <!ELEMENT post (#PCDATA)> <!ELEMENT age (#PCDATA)> <!ELEMENT employee (fio, post?, age?, contactsEmployee)> <!ATTLIST employee %idattr;> <!ELEMENT emplist (employee+)>

Полный листинг XML документа-примера, удовлетворяющего условиям DTD-описания:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE shop SYSTEM "MyShop.dtd"> <shop> <contactsShop> Наш адрес: <address>&address1;</address>, телефоны: <phone>8(905)613-90-06</phone>, <phone>785-45-22</phone>, факс:<fax>65765765</fax>, электронный ящик:<email>mymail@mail.ru</email> </contactsShop> <chassis id="c1" dateofsale="2005-11-12" price="22000" whosold="sae"> <case color="silver" type="atx" title="codegen"> <epu turbo="false">400</epu> </case> <motherboard> <title>Shuttle</title> <model>AN70</model> <chipset>nforce2</chipset>, sound, LAN 100Mbit </motherboard> <cpu model="amd" frequency="2000" fsb="400"/> <ram size="1024"/> <hdd model="Maxtor" size="80"/> <diskdrive type="cdrwdvdrw" model="NEC 4200" speed="48/24/48"/> <videocard type="nvidia" model="GeForce 5900 XT"/> </chassis> <chassis id="c2" dateofsale="2004-11-04" price="25000" whosold="iip"> <case type="matx" title="Thermaltake"> <epu turbo="true">300</epu> </case> <motherboard> <title>Abit</title> <model>A40J</model> <chipset>nforce2</chipset>, sound 8 channel, LAN 1Gbit, video </motherboard> <cpu frequency="3000"/> <ram size="512"/> <hdd model="Seagate" size="160"/> <hdd model="Maxtor" size="160"/> <diskdrive type="cdrwdvdrom" model="LG 456"/> </chassis> <image src="logotype"/> <emplist> <employee id="iip"> <fio>Иванов Иван Петрович</fio> <post>Менеджер</post> <age>12</age> <contactsEmployee> Адрес: <address>&address2;</address>, телефон: <phone>8(905)618-78-45</phone>, почта - <email>ivanpi@mail.com</email> </contactsEmployee> </employee> <employee id="sae"> <fio>Серёгин Александр Евгеньевич</fio> <post>Главный менеджер</post> <age>76</age> <contactsEmployee> Адрес: <address>&address2;</address>, телефон: <phone>8(910)788-98-11</phone> </contactsEmployee> </employee> </emplist> </shop>

3 XML Schema

3.1 Пространство имен XML

XML-документы могут конструироваться из элементов и атрибутов, определенных в разных схемах или DTD. Например, в WSDL-описании web-сервисов в рамках одного документа используются конструкции, определенные схемами языков WSDL, W3C XML Schema и SOAP. Так как разработка схем может вестись независимо, то при совместном их использовании возникает опасность конфликта имен элементов и атрибутов. Для разрешения этой проблемы был придуман механизм пространств имен XML (XML namespaces). Суть этого механизма в том, что с каждой схемой сопоставляется некоторый глобально-уникальный идентификатор, задаваемый в формате uri. Этот uri служит только для идентификации пространства имен, а не для извлечения фактической схемы на этапе валидации XML-документа. Это означает, что идентификатор пространства имен может и не соответствовать никакому актуальному ресурсу в сети.

Идея заключается в том, что идентификатор пространства имен совместно с именем элемента или атрибута из этого пространства имен образует глобально-уникальное имя, так как имена элементов и атрибутов в пределах одного пространства имен уникальны. Чтобы избавить от необходимости квалификации каждого элемента и атрибута сравнительно длинным uri, вместо них используют короткий префикс, который вводится в XML-документ с помощью атрибутов, которые имеют имя xmlns, либо префикс xmlns: и локальное имя. Атрибуты с именем xmlns используются для объявления пространства имен по умолчанию, а атрибуты с префиксом xmlns: используются для объявления префиксов, занимающих в данном XML-документе соответствующий идентификатор пространства имен. Сам префикс вводится локальным именем: xmlns:локальное_имя_префикса.

Введенные префиксы используются для квалификации элементов и атрибутов в виде: <ns_prefix:local_name>.

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

Пример:

<?xml version = "1.0" encoding = "UTF-8"?> <definitions xmlns = "http://shemas.xmlsoap.org/wsdl" xmlns:soap = "http://shemas.xmlsoap.org/wsdl/soap/" xmlns:xsd = "http://www.w3.org/2001/XMLSchema" xmlns:soapenc = "http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns = "http://johnheadlong.nightmail.ru/schemas/" > <types> <xsd:schema> <xsd:complexType name = "..."> ... </xsd:comlexType> ... </xsd:schema> </types> </definitions>

3.2 Краткое описание XML Schema

Язык схем – это XML-язык, предназначенный для описания структуры XML-документов. Сами описания, выполненные на языке схем, являются XML-документами. Элементы и атрибуты языка схем определены пространством имен http://www.w3.org/2001/XMLSchema.

Существенное отличие языка схем от DTD то, что здесь введено понятие «тип»: элементы и атрибуты определяются тем или иным типом. Важно то, что типы могут быть описаны отдельно от элементов и атрибутов. Язык схем поддерживает богатые возможности для описания новых типов на базе встроенных, либо описанных на языке схем типов.

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

Корневым элементом в языке схем является элемент schema, внутри которого описываются типы, элементы и атрибуты.

Полностью описывать язык схем я не буду, приведу только пример с комментариями. Вы можете посмотреть спецификацию языка схем, если вам нужна полная информация по нему. Кроме этого вам также может понадобится изучить язык XPath и регулярные выражения.

3.3 Пример XML-схемы

Данная XML-схема описывает ту же предметную область, что и пример DTD.

Схеме сопоставлено пространство имен myns и при этом предусмотрена квалификация элементов, определенных схемой, в документе, построенном на ее основе (атрибут elementFormDefault со значением qualified):

<schema xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns = "http://www.w3.org/2001/XMLSchema" xmlns:myns = "http://mixa1984.narod.ru/myschema.xsd" targetNamespace = "http://mixa1984.narod.ru/myschema.xsd" elementFormDefault = "qualified" >

Документ-пример содержит ссылку на XML-схему:

<myns:shop xmlns:myns = "http://mixa1984.narod.ru/myschema.xsd" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = http://mixa1984.narod.ru/myschema.xsd MyShop.xsd >

Схема демонстрирует использование конструкций для описания сложного типа, образованного вложенными элементами и атрибутами. Например, элемент epu вложен в элемент case, который, в свою очередь, вложен в элемент chassis. При описании сложных типов используются группы sequence, choice и all:

<complexType name = "epuType"> <simpleContent> <extension base = "myns:powerType"> <attribute name = "turbo" type = "boolean" use = "required"/> </extension> </simpleContent> </complexType> <element name = "epu" type = "myns:epuType"/> <complexType name = "caseType"> <sequence> <element name = "epu" type = "myns:epuType"/> </sequence> <attribute name = "color" type = "myns:colorList" use = "optional" default = "white"/> <attribute name = "type" type = "myns:typeType" use = "optional" default = "atx"/> <attribute name = "title" type = "string" use = "required"/> </complexType> <element name = "case" type = "myns:caseType"/> <complexType name = "chassisType"> <sequence> <element name = "case" type = "myns:caseType"/> <element name = "motherboard" type = "myns:motherboardType"/> <element name = "cpu" type = "myns:cpuType"/> <element name = "ram" type = "myns:ramType"/> <element name = "hdd" type = "myns:hddType" maxOccurs = "4"/> <element name = "diskdrive" type = "myns:diskdriveType" maxOccurs = "4"/> <element name = "videocard" type = "myns:videocardType" minOccurs = "0"/> </sequence> <attribute name = "id" type = "ID" use = "required"/> <attribute name = "dateofsale" type = "date" use = "required"/> <attribute name = "price" type = "positiveInteger" use = "required"/> <attribute name = "whosold" type = "string" use = "required"/> </complexType> <element name = "chassis" type = "myns:chassisType"/>

Схема содержит описание абстрактного сложного типа и элемента этого типа, а пример документа использует его:

<complexType name = "abstractContactsType" abstract = "true"/> <element name = "abstractContacts" type = "myns:abstractContactsType"/> <complexType name = "contactsType" mixed = "true"> <complexContent mixed = "true"> <extension base = "myns:abstractContactsType"> <sequence> <element name = "address" type = "string" minOccurs = "0"/> <element name = "phone" type = "string" minOccurs = "0" maxOccurs = "unbounded"/> <element name = "email" type = "myns:emailType" minOccurs = "0" maxOccurs = "unbounded"/> </sequence> </extension> </complexContent> </complexType> <myns:abstractContacts xsi:type = "myns:contactsType"/>

Схема демонстрирует описание нового сложного типа на базе как простого типа, так и сложного. Как путем расширения, так и путем ограничения:

<complexType name = "epuType"> <simpleContent> <extension base = "myns:powerType"> <attribute name = "turbo" type = "boolean" use = "required"/> </extension> </simpleContent> </complexType> <complexType name = "contactsType" mixed = "true"> <complexContent mixed = "true"> <extension base = "myns:abstractContactsType"> <sequence> <element name = "address" type = "string" minOccurs = "0"/> <element name = "phone" type = "string" minOccurs = "0" maxOccurs = "unbounded"/> <element name = "email" type = "myns:emailType" minOccurs = "0" maxOccurs = "unbounded"/> </sequence> </extension> </complexContent> </complexType> <complexType name = "contactsEmployeeType" mixed = "true"> <complexContent mixed = "true"> <restriction base = "myns:contactsType"> <sequence> <element name = "address" type = "string" minOccurs = "0"/> <element name = "phone" type = "string" minOccurs = "0"/> <element name = "email" type = "myns:emailType" minOccurs = "0" maxOccurs = "unbounded"/> </sequence> </restriction> </complexContent> </complexType>

В схеме используется возможность описания новых простых типов на базе существующих при помощи фасетов pattern (шаблон на языке регулярных выражений), enumeration и minInclusive/maxInclusive, а также списков и объединений:

<simpleType name = "powerType"> <restriction base = "string"> <pattern value = "\d{1,3} W"/> </restriction> </simpleType> <simpleType name = "colorType"> <restriction base = "string"> <enumeration value = "white"/> <enumeration value = "silver"/> <enumeration value = "black"/> <enumeration value = "red"/> <enumeration value = "blue"/> <enumeration value = "green"/> </restriction> </simpleType> <simpleType name = "ageType"> <restriction base = "positiveInteger"> <minInclusive value = "18"/> <maxInclusive value = "50"/> </restriction> </simpleType> <simpleType name = "colorList"> <list itemType = "myns:colorUnionType"/> </simpleType> <simpleType name = "colorUnionType"> <union memberTypes = "myns:colorType myns:colorCodeType"/> </simpleType>

Схема содержит описание ограничения уникальности, ключа и ссылки на ключ (здесь используются конструкции языка XPath):

<element name = "shop" type = "myns:shopType"> <unique name = "idEmployeeKey"> <selector xpath = "myns:emplist/myns:emloyee"/> <field xpath = "@id"/> </unique> <unique name = "idChassisKey"> <selector xpath = "myns:chassis"/> <field xpath = "@id"/> </unique> <key name = "employeeKey"> <selector xpath = "myns:emplist/myns:employee"/> <field xpath = "@id"/> </key> <keyref name = "employeeRef" refer = "myns:employeeKey"> <selector xpath = "myns:chassis"/> <field xpath = "@whosold"/> </keyref> </element>

Скачать полный исходный код XML-схемы.

Пример XML-документа, построенного по схеме:

<?xml version = "1.0" encoding = "windows-1251"?> <myns:shop xmlns:myns = "http://mixa1984.narod.ru/myschema.xsd" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://mixa1984.narod.ru/myschema.xsd MyShop.xsd"> <myns:contactsShop> Наш адрес: <myns:address>ул. Мира, д.15</myns:address>, телефоны: <myns:phone>8(905)616-90-05</myns:phone>, <myns:phone>785-45-22</myns:phone>, электронный ящик: <myns:email>mymail@mail.ru</myns:email>, факс:<myns:fax>65765765</myns:fax> </myns:contactsShop> <myns:abstractContacts xsi:type = "myns:contactsType"/> <myns:chassis id = "c1" dateofsale = "2004-11-04" price = "24000" whosold = "iip"> <myns:case color = "white" type = "matx" title = "Thermaltake"> <myns:epu turbo = "true">300 W</myns:epu> </myns:case> <myns:motherboard> <myns:chipset>nforce2</myns:chipset>, sound 8 channel, LAN 1Gbit, video </myns:motherboard> <myns:cpu model = "pentium" frequency = "3000" fsb = "800"/> <myns:ram size = "512"/> <myns:hdd model = "Seagate" size = "160"/> <myns:hdd model = "Maxtor" size = "160"/> <myns:diskdrive type = "cdrwdvdrom" model = "LG 456"/> </myns:chassis> <myns:chassis id = "c2" dateofsale = "2005-11-12" price = "17000" whosold = "sae"> <myns:case color = "silver" type = "atx" title = "codegen"> <myns:epu turbo = "false">400 W</myns:epu> </myns:case> <myns:motherboard> <myns:title>Shuttle </myns:title> </myns:motherboard> <myns:cpu model = "amd" frequency = "2000" fsb = "400"/> <myns:ram size = "1024"/> <myns:hdd model = "Maxtor" size = "80"/> <myns:diskdrive type = "cdrwdvdrw" model = "NEC 4200" speed = "48/24/48"/> <myns:videocard type = "nvidia" model = "GeForce 5900 XT"/> </myns:chassis> <myns:image src = "logo.gif"/> <myns:emplist> <myns:employee id = "iip"> <myns:fio>Иванов Иван Петрович</myns:fio> <myns:post>Менеджер</myns:post> <myns:age>22</myns:age> <myns:contactsEmployee> Адрес: <myns:address>ул. Василия, д. 11, кв. 56</myns:address>, телефон: <myns:phone>8(905)618-78-45</myns:phone>, почта - <myns:email>ivanpi@mail.com</myns:email> </myns:contactsEmployee> </myns:employee> <myns:employee id = "sae"> <myns:fio>Серёгин Александр Евгеньевич</myns:fio> <myns:post>Главный менеждер</myns:post> <myns:age>35</myns:age> <myns:contactsEmployee> Адрес: <myns:address>ул. Константина, д. 12, кв. 65</myns:address>, телефон: <myns:phone>8(910)788-98-11</myns:phone> </myns:contactsEmployee> </myns:employee> </myns:emplist> </myns:shop>
В начало страницы

Hosted by uCoz