Журнал ВРМ World

Мировая история развития технологий управления эффективностью бизнеса – обзоры зарубежных публикаций

Основы использования XML Schema для определения элементов

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

Содержание:

  1. Использование пространств имен
  2. Определение элементов
  3. Выражение ограничений
  4. Выход за пределы основ
  5. Ресурсы

XML Schema, в настоящее время приближающаяся к принятию в качестве рекомендации W3C, призвана обеспечить богатую грамматическую структуру для XML-документов и преодолеть ограничения, присущие DTD (см. справа Ограничения DTD). Эта статья демонстрирует гибкость XML Schema и показывает, как определить фундаментальное понятие XML-документов - элемент - в рамках XML Schema.

XML Schema выразительнее DTD. Первые три листинга производят краткое сравнение различных путей представления элементов. Листинг 1 показывает фрагмент XML-документа. Листинг 2 демонстрирует объявление этих двух элементов в синтаксисе DTD, а Листинг 3 соответствующий синтаксис XML Schema. Заметьте, что синтаксис в Листинге 3 совпадает с синтаксисом XML. При использовании XML Schema парсер с проверкой допустимости может удостовериться, что элемент InvoiceNo является положительным целым, а элемент ProductID состоит из одной буквы от A до Z, сопровождаемой шестью цифрами. В отличие от этого, прасер с проверкой допустимости документа, использующий DTD, может лишь проверить, что эти элементы представлены как строки.


Листинг 1: Фрагмент XML-документа

<InvoiceNo>123456789</InvoiceNo>
<ProductID>J123456</ProductID>

Листинг 2: Фрагмент DTD, описывающий элементы из Листинга 1

<!ELEMENT InvoiceNo (#PCDATA)>
<!ELEMENT ProductID (#PCDATA)>

Листинг 3: Фрагмент XML Schema, описывающий элементы из Листинга

<element name='InvoiceNo' type='positive-integer'/>
<element name='ProductID' type='ProductCode'/>
<simpleType name='ProductCode' base='string'>
<pattern value='[A-Z]{1}d{6}'/></simpleType>

Использование пространств имен в XML Schema.

В реальном мире один человек может обрабатывать документы от множества корреспондентов, которые могут хотеть по разному представлять свои данные. Более того, в рамках одногодокумента они могут нуждаться в раздельном обращении к элементам с одними и теми же именами, но в разных контекстах. Как различить друг от друга эти разные определения, имеющие одно и то же имя? XML Schema позволяет различать такие определения с помощью понятия пространства имен.

Ограничения шаблонов DTD
Несмотря на то, что шаблоны DTD отлично служили разработчикам SGML и HTML на протяжении 20 лет в качестве механизма описания структурированной информации, шаблоны DTD имеют строгие ограничения по сравнению со XML Schema. DTD требует, чтобы элементы состояли из одного из трех понятий:
  • Текстовой строки
  • Текстовой строки, и других дочерних элементов
  • Набора дочерних элементовDTD не имеет синтаксиса XML и предлагает только ограниченную поддержку для типов или пространств имен.

Данная XML Schema определяет набор новых имен, таких, как имена элементов, типов, атрибутов, групп атрибутов, чьи определения и объявления записаны в схеме. Листинг 3 определяет имена InvoiceNo, ProductID и ProductCode.

Говорят, что имена, определенные в схеме, принадлежат собственному пространству имен. Пространство имен само по себе имеет фиксированное, но произвольное имя, которое должно придерживаться синтаксиса URL. Например, вы можете установить имя пространства имен для схемы, фрагмент которой приведен в Листинге 3 в виде: http://www.SampleStore.com/Account.

Однако даже если пространство имен начинается с http://, оно не является URL файла, содержащего определение схемы. В действительности, URL http://www.SampleStore.com/Account вообще не относится ни к какому файлу, а только к присвоенному имени.

Определения и объявления в схеме могут обращаться к именам, принадлежащим другим пространствам имен. В этой статье мы называем такие пространства имен используемыми пространствами имен (source namespaces). Каждая схема имеет одно собственноепространство имен и, возможно, множество используемых пространств имен. Фактически, каждое имя в данной схеме принадлежит какому-либо пространству имен. Имена для пространств имен могут быть достаточно длинными, однако они они могут быть сокращены до аббревиатуры с помощью синтаксиса объявления xmlns в документе схемы XML. Чтобы проиллюстрировать эти понятия, мы можем кое-что добавить к примерной схеме, как это показано в Листинге 4.


Листинг 4: Собственные и используемые пространства имен

<!--XML Schema fragment in file schema1.xsd-->

<xsd:schema targetNamespace='http://www.SampleStore.com/Account'
            xmlns:xsd='http://www.w3.org/1999/XMLSchema'
            xmlns:ACC='http://www.SampleStore.com/Account'>
<xsd:element name='InvoiceNo' type='xsd:positive-integer'/>
<xsd:element name='ProductID' type='ACC:ProductCode'/>
<xsd:simpleType name='ProductCode' base='xsd:string'>
<xsd:pattern value='[A-Z]{1}d{6}'/>
</xsd:simpleType>

В XML Schema из Листинга 4 имя targetNamespace представлено как http://www.SampleStore.com/Accountt и содержит имена 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



Фрагмент схемы в Листинге 4 не нуждается в специальном определении местоположения файлов исходной схемы. Для общей "схемы схем" http://www.w3.org/1999/XMLSchema вам нет необходимости определять местоположение , так как оно хорошо известно. Для используемого пространства имен http://www.SampleStore.com/Account вам не нужно определять местоположение, поскольку это только имя собственного пространства имен, определенного в этом файле. Для лучшего понимания того, как определить местоположение схемы и использовать пространство имен по умолчанию, рассмотрите расширение примера, приведенное в Листинге 5.


Листинг 5: Множественные исходные пространства имен, импортирующие пространство имен.

<!--XML Schema fragment in file schema1.xsd-->
<schema targetNamespace='http://www.SampleStore.com/Account'
        xmlns='http://www.w3.org/1999/XMLSchema'
        xmlns:ACC= 'http://www.SampleStore.com/Account'
        xmlns:PART= 'http://www.PartnerStore.com/PartsCatalog'>
<import namespace='http://www.PartnerStore.com/PartsCatalog'
        schemaLocation='http://www.ProductStandards.org/repository/alpha.xsd'/>
<element name='InvoiceNo' type='positive-integer'/>
<element name='ProductID' type='ACC:ProductCode'/>
<simpleType name='ProductCode' base='string'>
<pattern value='[A-Z]{1}d{6}'/>
</simpleType>
<element name='stickyGlue' type='PART:SuperGlueType'/>

Листинг 5 включает еще одну ссылку на пространство имен: http://www.PartnerStore.com/PartsCatalog. Это пространство имен отлично от targetNamespace и от стандартных пространств имен. Поэтому оно должно импортироваться с использованием элемента объявления import, атрибут schemaLocation которого определяет местоположение файла, содержащего схему. Пространством имен по умолчанию является http://www.w3.org/1999/XMLSchema, чье объявление xmlns не имеет имени. Каждое неквалифицированное имя, как, например, schema и element, принадлежит пространству имен по умолчанию http://www.w3.org/1999/XMLSchema. Если ваша схема обращается к нескольким именам из одного пространства имен, удобнее описать его как пространство имен по умолчанию.

Конкретный XML-документ может обращаться к именам элементов из множества пространств имен, определенных во множестве схем. Обратиться к сокращенному имени пространства имен можно используя объявленияме xmlns. Для определения местоположения файлов мы использовали атрибут schemaLocation из примера пространства имен схемы XML . Заметьте, что этот атрибут отличается от атрибута с тем же именем schemaLocation в пространстве имен xsd в предыдущих примерах.


Листинг 6: Использование множества пространств имен из множества схем

<?xml version="1.0"?>
<ACC:rootElement xmlns:ACC='http://www.SampleStore.com/Account'
                 xmlns:PART='http://www.PartnerStore.com/PartsCatalog'
                 xmlns:xsi='http://www.w3.org/1999/XMLSchema-instance'
                 xsi:schemaLocation='http://www.PartnerStore.com/PartsCatalog'
                                     http://www.ProductStandards.org/repository/alpha.xsd
                                     http://www.SampleStore.com/Account
                                     http://www.SampleStore.com/repository/schema1.xsd'>
<ACC:InvoiceNo>123456789</ACC:InvoiceNo>


Рисунок 2: Пространства имен для Листингов 5 и 6



Определение элементов.

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

Простые типы
Спецификация XML Schema определяет набор простых типов, приведенный в Tаблице 2: Предопределеные простые типы.

Тип может быть простым или сложным. Простой тип не может содержать элементы или атрибуты. Сложный тип может содержать вложенные элементов и атрибуты. (Примеры приведенные выше в этой статье являются простыми типами (см. ProductCode)). Спецификация XML Schema включает также предопределенные простые типы (см. справа Простые типы). Производный простой тип может принимать значения внутри множества допустимых значений своего базового типа. Например, значения производного простого типа ProductCode представляют собой подмножество значений базового типа string.


Простые невложенные элементы имеют простой тип

Элемент, не содержащий атрибутов или других элементов может быть определен как имеющий простой тип, предварительно определен или определен пользователем так, как string, integer, decimal, time, ProductCode и др.


Листинг 7: Несколько простых типов для элементов

<element name='age' type='integer'/>
<element name='price' type='decimal'/>

Элементы с атрибутами должны иметь сложный тип

Если Вы попробуете добавить атрибут currency к простому элементу price из Листинга 7, то это приведет к ошибке. Элемент простого типа не может иметь атрибуты. Если вы хотите добавить атрибут, вы должны определить price как сложный тип. В примере Листинга 8 мы определили, что тип называется неименованным (an anonymous type), если не задано явного имени. Другими словами, атрибут name элемента complexType не определен.


Листинг 8: Сложный тип элемента

<element name='price'>
  <complexType base='decimal' derivedBy='extension'>
    <attribute name='currency' type='string'/>
  </complexType>
</element>
<!-- In XML instance document, we can write:<price currency='US'>45.50</price> -->

Элементы, имеющие вложенные элементы, должны иметь сложный тип

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


Таблица 1: Сравнение сложных типов данных в DTD и XML Schema.

XML-документ
<Book>
  <Title>Cool XML<Title>
  <Author>Cool Guy</Author>
</Book>
DTD
<!ELEMENT Book (Title, Author)>
<!ELEMENT Title (#PCDATA)>
<!ELEMENT Author (#PCDATA)>
XML Schema
<element name='Book' type='BookType'/>
<complexType name='BookType'>
  <element name='Title' type='string'/>
  <element name='Author' type='string'/>
</complexType>

Хотя код XML в Tаблице 1 соответствует фрагментам и DTD и XML Schema, между ними есть большое различие. В DTD все элементы глобальные, тогда как XML Schema в этой таблице позволяет локальные элементы Title и Author в контексте элемента Book. Для точного дублирования эффекта объявлений DTD в XML Schema элементы Title и Author должны иметь глобальную область видимости, как в Листинге 9. Атрибут ref элемента element позволяет Вам обращаться к ранее объявленным элементам.


Листинг 9: Сложный тип, определенный с помощью глобальных простых типов

<element name='Title' type='string'/>
<element name='Author' type='string'/>
<element name='Book' type='BookType'/>
<complexType name='BookType'>
  <element ref='Title'/>
  <element ref='Author'/>
</complexType>

В примерах Таблицы 1 и Листинга 9 BookType является глобальным и может использоваться для определения других элементов. В отличие от этого, Листинг 10 определяет BookType локально в элементе Book и, кроме того, делает его неименованным. Заметьте, что фрагмент XML-документа в Таблице 1 соответствует всем трем фрагментам схемы в Таблице 1, Листинге 9 и Листинге 10.


Листинг 10: Скрытие BookType как локального типа

<element name='Title' type='string'/>
<element name='Author' type='string'/>
<element name='Book'>
  <complexType>
    <element ref='Title'/>
    <element ref='Author'/>
  </complexType>
</element>

Накладывание сложных условий на элементы

XML Schema предоставляет гораздо большую гибкость для задания условий, налагаемых на модель содержания элементов, чем DTD. На простейшем уровне, как в DTD, вы можете связывать атрибуты с элементами и определитьколичество вхождений элементов( только одно , нуля или одного (?), нуля или более (*), или одного или более (+) элементов из данного набора. В XML Schema вы можете выразить также дополнительные ограничения, используя, например, атрибуты minOccurs и maxOccurs элемента element, а также с помощью элементов choice, group, и all.


Листинг 11: Выражение ограничений на типы элементов

<element name='Title' type='string'/>
<element name='Author' type='string'/>
<element name='Book'>
  <complexType>
    <element ref='Title' minOccurs='0'/>
    <element ref='Author' maxOccurs='2'/>
  </complexType>
</element>

В Листинге 11 появление Title необязательно в Book (аналогично '?' в DTD). Тем не менее, Листинг 11 также говорит, что должен быть хотя бы один, но не более двух, авторов в элементе Book. Значением по умолчанию minOccurs и maxOccurs будет 1 для элемента element. Элемент choice позволяет появится в примере только одному из своих дочерних элементов. Другой элемент, all, выражает ограничение, определяющее, что все дочерние элементы в группе могут появляться однажды или не появляться вовсе, и что они могут появляться в любом порядке. Листинг 12 выражает ограничение, обязывающее и Title и Author появляться в любом порядке в Book или не появляться вообще. Такие ограничения трудны для выражения в DTD.


Листинг 12: Индикация того, что для элемента должны быть определены все типы

<xsd:element name='Title' type='string'/>
<xsd:element name='Author' type='string'/>
<xsd:element name='Book'>
  <xsd:complexType>
    <xsd:all>
      <xsd:element ref='Tile'/>
      <xsd:element ref='Author'/>
    </xsd:all>
  </xsd:complexType>
</xsd:element>

Мы охватили наиболее фундаментальные понятия, необходимые для определения элементов в XML Schema, дав вам представление о его возможностях с помощью простых примеров. Но имеется и множество гораздо более мощных механизмов:

  • XML Schema включает в себя расширенную поддержку наследования типов, дающего возможность повторно использовать ранее определенные структуры. Используя конструкцию faset, вы можете получить новые типы, представляющие подмножества значений других типов. В примере для этой статьи тип ProductCode был определен с использованием типа pattern. Подтип может также добавить объявления элементов и атрибутов к базовому типу.
  • Некоторые механизмы могут контролировать, может ли подтип вообще быть определен или замещен в конкретном документе. Например, возможно выразить тот факт, что InvoiceType (тип номера счета-фактуры) не может иметь подтипы, то есть никто не сможет определить новую версию InvoiceType. Вы можете также выразить то, что в конкретном контексте не может быть замещен ни какой подтип типа ProductCode.
  • Кроме создания подтипов, возможно определять эквивалентность типов, так, что значение одного типа может быть заменено с помощью другого типа.
  • Объявляя элемент или тип абстрактным, XML Schema обеспечивает механизм для его принудительной замены.
  • Для удобства, группы атрибутов и элементов могут быть определены и поименованы. Это дает возможность повторного использования путем последующего обращения к группам.
  • XML Schema предлагает три элемента - appInfo, documentation и annotation - для аннотирования схем как для читателей (documentation), так и для приложений (appInfo).
  • Вы можете выразить ограничение уникальности, основанное на определенных атрибутах дочерних элементов.

Вы можете продолжить исследование схемы XML с помощью документации на сайте W3C (см. Ресурсы) и просматривая для лучшего охвата зону dW XML. Сейчас, когда спецификация схемы XML была принята как рекомендация W3C, ее будет использовать все большее и большее число людей.

Ресурсы

Автор: Эшвин Радия, Вибха Дайксит