Een XSD voorbeeld

Deze sectie zal u leren hoe u een XML Schema kunt schrijven. U zult ook verschillende methoden leren om schema's te schrijven.

XML-document

Laten we dit XML-document genaamd "shiporder.xml" bekijken:

<?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>

Het bovenstaande XML-document bevat de root-element "shiporder", die een vereiste eigenschap "orderid" bevat. Het element "shiporder" bevat drie verschillende sub-elementen: "orderperson", "shipto" en "item". Het element "item" verschijnt tweemaal, het bevat een "title", een optionele "note"-element, een "quantity" en een "price"-element.

Deze regel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" geeft de XML-parser aan om de document te valideren op basis van een schema. Deze regel: xsi:noNamespaceSchemaLocation="shiporder.xsd" bepaalt de locatie van het schema (hier bevindt het zich in dezelfde map als "shiporder.xml").

Maak een XML Schema aan

Nu moeten we een schema maken voor de bovenstaande XML-document.

We kunnen beginnen met het openen van een nieuw bestand en deze te noemen "shiporder.xsd". Om een schema te maken, moeten we eenvoudig volgen van de structuur van het XML-document en elk element dat we vinden definiëren. We beginnen met het definiëren van een standaard XML-declaratie:

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

In het bovenstaande schema hebben we de standaard naamruimte (xs) gebruikt, die geassocieerd is met de Schema Language Definition (Schema language definition), whose standaardwaarde http://www.w3.org/2001/XMLSchema is.

Daarna moeten we het "shiporder"-element definiëren. Dit element heeft een eigenschap die andere elementen bevat, dus we beschouwen het als een complex type. De onderliggende elementen van het "shiporder"-element worden omgeven door het xs:sequence-element, dat de volgorde van de onderliggende elementen definieert:

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

Daarna moeten we het "orderperson"-element definiëren als een eenvoudige type (dus omdat het geen eigenschappen of andere elementen bevat). De voorvoegsel van het type (xs:string) wordt bepaald door de prefix van de naamruimte, die geassocieerd is met de XML schema die de vooraf gedefinieerde schema-datatype-indicaties bevat:

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

Daarna moet ik de twee elementen definiëren als complexe typen: "shipto" en "item". We beginnen met het definiëren van het "shipto"-element:

<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>

Door schema kunnen we de maxOccurs- en minOccurs-eigenschappen gebruiken om het aantal keren dat een element kan voorkomen te definiëren. maxOccurs definieert het maximale aantal keren dat een element kan voorkomen, terwijl minOccurs het minimale aantal keren definieert. De standaardwaarden van maxOccurs en minOccurs zijn beide 1!

Nu kunnen we het "item"-element definiëren. Dit element kan meerdere keren binnen het "shiporder"-element voorkomen. Dit wordt bereikt door de waarde van de maxOccurs-eigenschap van het "item"-element in te stellen op "unbounded", zodat het "item"-element kan voorkomen zo vaak als de maker dat wil. Let op, het "note"-element is een optionele element. We hebben de minOccurs-eigenschap van dit element ingesteld op 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"/>

这是这个名为 "shiporder.xsd" 的 schema 文件的文档清单:

<?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>

Gebruik van gespecificeerde typen (Benaming van Typen)

De derde ontwerpmethode definieert klassen of typen, zodat we de definities van elementen kunnen hergebruiken. De manier waarop is: eerst de naam van de eenvoudige en complexe elementen noemen, en vervolgens verwijzen naar hen via het type-eigenschap van het element.

Dit is een schema-bestand ontworpen met de derde methode ("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>

Het element "restriction" toont aan dat de datatypen afkomstig zijn van de W3C XML Schema-namenruimte. Daarom betekent het volgende fragment dat de waarde van het element of de eigenschap een typewaarde van het type string moet zijn:

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

De element "restriction" wordt vaak gebruikt om elementen beperkingen op te leggen. Bekijk hieronder enkele fragmenten uit het bovenstaande schema:

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

Deze code geeft aan dat de waarde van het element of de eigenschap een string moet zijn en dat deze een opeenvolging van zes opeenvolgende tekens moet zijn, en deze tekens moeten cijfers 0-9 zijn.