Пример XSD

Эта глава покажет вам, как пишется XML Schema. Вы также узнаете о различных методах написания schema.

XML-документ

Давайте посмотрим на этот XML-документ с именем "shiporder.xml":

<?xml version="1.0" encoding="ISO-8859-1"?>
<shiporder orderid="889923">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
 <orderperson>George Bush</orderperson>
 <shipto>
  <name>John Adams</name>
  <address>Oxford Street</address>
  <city>London</city>
  <country>UK</country>
 </shipto>
 <item>
  <title>Empire Burlesque</title>
  <note>Special Edition</note>
  <quantity>1</quantity>
  <price>10.90</price>
 </item>
 <item>
  <title>Hide your heart</title>
  <quantity>1</quantity>
  <price>9.90</price>
 </item>
</shiporder>

Этот XML-документ включает корневой элемент "shiporder", который содержит атрибут с именем "orderid". Элемент "shiporder" содержит три различных подэлемента: "orderperson", "shipto" и "item". Элемент "item" встречается дважды, он содержит "title", необязательный элемент "note", "quantity" и элемент "price".

Эта строка xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" информирует XML-парсер о том, что документ должен быть проверен по определенному schema. Эта строка: xsi:noNamespaceSchemaLocation="shiporder.xsd" определяет местоположение schema (здесь, оно находится в той же папке, что и "shiporder.xml").

Создайте XML Schema

Теперь нам нужно создать схему для этого XML документа.

Мы можем начать с открытия нового файла и назвать его "shiporder.xsd". Чтобы создать схему, нам нужно просто следовать структуре XML документа, определяя каждый обнаруженный элемент. Сначала мы начинаем с определения стандартного объявления XML:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
...
</xs:schema>

В приведенной выше схеме мы используем стандартное пространство имен (xs), которое связано с URI Schema language definition (Schema language definition), его стандартным значением является http://www.w3.org/2001/XMLSchema.

Далее нам нужно определить элемент "shiporder" как составной тип. Этот элемент имеет атрибут, который содержит другие элементы, поэтому мы определяем его как составной тип. Подэлементы элемента "shiporder" окружены элементом xs:sequence, который определяет порядок подэлементов:

<xs:element name="shiporder">
 <xs:complexType>
  <xs:sequence>
  ...
  ...
  </xs:sequence>
  ...
 </xs:complexType>
</xs:element>

Затем нам нужно определить элемент "orderperson" как элемент простого типа (поскольку он не содержит ни атрибутов, ни других элементов). Префикс типа (xs:string) определяется префиксом пространства имен, которое связано с XML schema, указывающим на предопределенные типы данных schema:

<xs:element name="orderperson" type="xs:string"/>

Далее я хочу определить два элемента как составные типы: "shipto" и "item". Начнем с определения элемента "shipto":

<xs:element name="shipto">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="name" type="xs:string"/>
   <xs:element name="address" type="xs:string"/>
   <xs:element name="city" type="xs:string"/>
   <xs:element name="country" type="xs:string"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>

Через схему мы можем использовать атрибуты maxOccurs и minOccurs для определения возможного числа出现的 элементов. Атрибут maxOccurs определяет максимальное число出现的 элементов, а minOccurs определяет минимальное число出现的 элементов. Значением по умолчанию для maxOccurs и minOccurs является 1!

Теперь мы можем определить элемент "item". Этот элемент может появляться внутри элемента "shiporder" несколько раз. Это достигается установкой значения атрибута maxOccurs элемента "item" в "unbounded", что позволяет элементу "item" появляться столько раз, сколько wished создатель.

<xs:element name="item" maxOccurs="unbounded">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="title" type="xs:string"/>
   <xs:element name="note" type="xs:string" minOccurs="0"/>
   <xs:element name="quantity" type="xs:positiveInteger"/>
   <xs:element name="price" type="xs:decimal"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>

Теперь мы можем声明 атрибуты элемента "shiporder". Поскольку это обязательный атрибут, мы определяем use="required".

Комментарий:Декларация этого свойства должна быть помещена в конце:

<xs:attribute name="orderid" type="xs:string" use="required"/>

Это список документов для этого schema файла с именем "shiporder.xsd":

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="shiporder">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="orderperson" type="xs:string"/>
   <xs:element name="shipto">
    <xs:complexType>
     <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="address" type="xs:string"/>
      <xs:element name="city" type="xs:string"/>
      <xs:element name="country" type="xs:string"/>
     </xs:sequence>
    </xs:complexType>
   </xs:element>
   <xs:element name="item" maxOccurs="unbounded">
    <xs:complexType>
     <xs:sequence>
      <xs:element name="title" type="xs:string"/>
      <xs:element name="note" type="xs:string" minOccurs="0"/>
      <xs:element name="quantity" type="xs:positiveInteger"/>
      <xs:element name="price" type="xs:decimal"/>
     </xs:sequence>
    </xs:complexType>
   </xs:element>
  </xs:sequence>
  <xs:attribute name="orderid" type="xs:string" use="required"/>
 </xs:complexType>
</xs:element>
</xs:schema>

Разделение Schema

Предыдущий метод дизайна очень прост, но когда документ сложен, его чтение и поддержка становятся сложными.

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

Это schema файл, спроектированный новым методом:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- 简易元素的定义 -->
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
<!-- Определение свойств -->
<xs:attribute name="orderid" type="xs:string"/>
<!-- Определение сложных элементов -->
<xs:element name="shipto">
 <xs:complexType>
  <xs:sequence>
   <xs:element ref="name"/>
   <xs:element ref="address"/>
   <xs:element ref="city"/>
   <xs:element ref="country"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>
<xs:element name="item">
 <xs:complexType>
  <xs:sequence>
   <xs:element ref="title"/>
   <xs:element ref="note" minOccurs="0"/>
   <xs:element ref="quantity"/>
   <xs:element ref="price"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>
<xs:element name="shiporder">
 <xs:complexType>
  <xs:sequence>
   <xs:element ref="orderperson"/>
   <xs:element ref="shipto"/>
   <xs:element ref="item" maxOccurs="unbounded"/>
  </xs:sequence>
  <xs:attribute ref="orderid" use="required"/>
 </xs:complexType>
</xs:element>
</xs:schema>

Использование指定的 типов (Именованные типы)

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

Это схема файла, созданная с помощью третьего метода ("shiporder.xsd"):

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="stringtype">
 <xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="inttype">
 <xs:restriction base="xs:positiveInteger"/>
</xs:simpleType>
<xs:simpleType name="dectype">
 <xs:restriction base="xs:decimal"/>
</xs:simpleType>
<xs:simpleType name="orderidtype">
 <xs:restriction base="xs:string">
  <xs:pattern value="[0-9]{6}"/>
 </xs:restriction>
</xs:simpleType>
<xs:complexType name="shiptotype">
 <xs:sequence>
  <xs:element name="name" type="stringtype"/>
  <xs:element name="address" type="stringtype"/>
  <xs:element name="city" type="stringtype"/>
  <xs:element name="country" type="stringtype"/>
 </xs:sequence>
</xs:complexType>
<xs:complexType name="itemtype">
 <xs:sequence>
  <xs:element name="title" type="stringtype"/>
  <xs:element name="note" type="stringtype" minOccurs="0"/>
  <xs:element name="quantity" type="inttype"/>
  <xs:element name="price" type="dectype"/>
 </xs:sequence>
</xs:complexType>
<xs:complexType name="shipordertype">
 <xs:sequence>
  <xs:element name="orderperson" type="stringtype"/>
  <xs:element name="shipto" type="shiptotype"/>
  <xs:element name="item" maxOccurs="unbounded" type="itemtype"/>
 </xs:sequence>
 <xs:attribute name="orderid" type="orderidtype" use="required"/>
</xs:complexType>
<xs:element name="shiporder" type="shipordertype"/>
</xs:schema>

Элемент ограничения показывает, что тип данных来源于 тип данных в пространстве имен W3C XML Schema. Таким образом, следующий фрагмент означает, что значение элемента или атрибута должно быть строковым значением:

<xs:restriction base="xs:string">

Элемент ограничения часто используется для наложения ограничений на элементы. Посмотрите на следующие фрагменты из вышеприведенного schema:

<xs:simpleType name="orderidtype">
 <xs:restriction base="xs:string">
  <xs:pattern value="[0-9]{6}"/>
 </xs:restriction>
</xs:simpleType>

Этот код указывает, что значение элемента или атрибута должно быть строкой и должно состоять из шести последовательных символов, и эти символы должны быть числами от 0 до 9.