XSD 示例
本章將演示如何編寫 XML Schema。您還將瞭解到 Schema 可以以不同的方式編寫。
一個 XML 文件
我們來看一個名為“shiporder.xml”的 XML 文件
<?xml version="1.0" encoding="UTF-8"?>
<shiporder orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
<address>Langgt 23</address>
<city>4000 Stavanger</city>
<country>Norway</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 文件建立一個 Schema。
我們首先開啟一個新檔案,並將其命名為“shiporder.xsd”。要建立 Schema,我們可以簡單地按照 XML 文件中的結構進行操作,併為我們找到的每個元素進行定義。我們將從標準的 XML 宣告開始,然後是定義 Schema 的 xs:schema 元素
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
</xs:schema>
在上面的 Schema 中,我們使用了標準名稱空間 (xs),與此名稱空間關聯的 URI 是 Schema 語言定義,其標準值為 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>
使用 Schema,我們可以使用 maxOccurs 和 minOccurs 屬性定義元素的可能出現次數。maxOccurs 指定元素的最多出現次數,minOccurs 指定元素的至少出現次數。maxOccurs 和 minOccurs 的預設值均為 1!
現在我們可以定義“item”元素。這個元素可以在“shiporder”元素內部多次出現。這是透過將“item”元素的 maxOccurs 屬性設定為“unbounded”來指定的,這意味著作者可以根據需要多次出現“item”元素。請注意,“note”元素是可選的。我們透過將 minOccurs 屬性設定為零來指定這一點
<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="UTF-8" ?>
<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 檔案 ("shiporder.xsd") 的新設計
<?xml version="1.0" encoding="UTF-8" ?>
<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>
使用命名型別
第三種設計方法定義了類或型別,這使我們能夠重用元素定義。這是透過命名 simpleTypes 和 complexTypes 元素,然後透過元素的 type 屬性指向它們來完成的。
這是 Schema 檔案 ("shiporder.xsd") 的第三種設計
<?xml version="1.0" encoding="UTF-8" ?>
<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 之間的數字。