一个 XSD 实例

Ang sektor na ito ay magpapakita sa iyo kung paano magsulat ng isang XML Schema. Magsasalita din ka ng iba't ibang pamamaraan sa pagsusulat ng schema.

XML dokumento

Hagingi natin ang XML dokumentong pinangalanang "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>

Ang XML dokumento na ito ay may pangunahing elemento na "shiporder", na mayroong katangian na may pangalang "orderid". Ang elemento na "shiporder" ay may tatlong iba't ibang pangalawang elemento: "orderperson", "shipto" at "item". Ang elemento na "item" ay lumitaw dalawang beses, na mayroong "title", isang opisyal na "note" elemento, isang "quantity" at isang "price" elemento.

Ang linya na ito xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ay nagsasabi sa XML parser na patunayan ang dokumento ayon sa isang schema. Ang linya na ito: xsi:noNamespaceSchemaLocation="shiporder.xsd" ay nagtutukoy sa lokasyon ng schema (dito, ito ay nasa parehong folder na ang "shiporder.xml").

Gumawa ng isang XML Schema

Ngayon, kailangan naming gumawa ng schema para sa itaas na XML dokumento.

Maaari naming magsimula sa pagbubukas ng isang bagong file at ipangalan ito na "shiporder.xsd". Upang gumawa ng schema, kailangan lang naming sundin ang estraktura ng dokumentong XML, at tanggapin ang bawat elemento na natuklasan namin. Una, magsimula kami sa pagtanggap ng isang standard na XML declaration:

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

Sa itaas na schema, gumamit kami ng pangkaraniwang namespace (xs), na nauugnay sa uri ng Schema language definition, na may standard na halaga na http://www.w3.org/2001/XMLSchema.

Susunod na, kailangan naming tanggapin ang "shiporder" elemento. Ang elemento na ito ay may attribute na naglalaman ng iba pang elemento, kaya inaakala namin ito bilang kumplikadong uri. Ang mga anak ng "shiporder" elemento ay napalibutan ng elemento na xs:sequence, na nagtutukoy sa pagkakasunod-sunod ng mga anak:

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

Pagkatapos, kailangan naming tanggapin ang "orderperson" elemento bilang madaliang uri (ito ay dahil wala itong anumang attribute o iba pang elemento). Ang prefix ng uri ng uri (xs:string) ay tinukoy ng prefix ng namespace, na nauugnay sa XML schema na naglalayong predetinidong uri ng schema data type:

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

Susunod na, kailangan kong tanggapin ang dalawang elemento bilang kumplikadong uri: "shipto" at "item". Magsimula kami sa pagtanggap ng "shipto" elemento:

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

Sa pamamagitan ng schema, maaari naming gamitin ang mga attribute na maxOccurs at minOccurs upang tanggapin ang bilang na maaaring lumitaw ng anumang elemento. Ang maxOccurs ay nagtutukoy sa pinakamataas na bilang na maaaring lumitaw ng anumang elemento, habang ang minOccurs ay nagtutukoy sa pinakamaliit na bilang na maaaring lumitaw ng anumang elemento. Ang default na halaga ng maxOccurs at minOccurs ay 1!

Ngayon, maaari nating tanggapin ang "item" elemento. Ang elemento na ito ay maaaring lumitaw maraming beses sa loob ng "shiporder" elemento. Ito ay ginawa sa pamamagitan ng pagtatakda ng halaga ng attribute na maxOccurs ng "item" elemento na "unbounded", kaya ang "item" elemento ay maaaring lumitaw sa anumang bilang na hiniling ng gumagawa. Isasaalang-alang, ang "note" elemento ay opisyal na elemento. Nakatakdang itong elementong minska na halaga ng attribute na minOccurs ay 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>

Gamit ang tinukoy na uri (Named Types)

Ang ikatlong paraan ng desinyo ay nagtatalaga ng klase o uri, upang magkaroon kami ng kakayahan na magsalita ng pagkakakilanlan ng elemento. Ang paraan nito ay: unang pinangalanan ang madaling elemento at kompleksong elemento, pagkatapos ay sa pamamagitan ng attribute na type ng elemento na inilalagay ang kanilang direksyon.

Ito ay isang schema na dinisenyo gamit ang ikatlong paraan ("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 的数字。