Пример 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-документа и определить каждый найденный элемент. Сначала мы начинаем с определения стандартного declarations 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" появляться столько раз, сколько хочет создатель. Обратите внимание, что элемент "note" является опциональным. Мы уже установили значение атрибута minOccurs этого элемента в 0:

<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

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

Следующий метод проектирования основан на том, что сначала определяются все элементы и атрибуты, а затем ониreferenced с помощью атрибута 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>

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

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

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

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

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