XML Schema 簡介
XSD 為何使用XML Schema 是基於 XML 的 DTD 替代者。XML Schema 可描述 XML 文檔的結構。XML Schema 語言也可作為 XSD(XML Schema Definition)來引用。
在繼續學習之前,您需要對下面的知識有基本的了解:HTML / XHTMLXML 以及 XML 命名空間對 DTD 的基本了解
XML Schema 的作用是定義 XML 文檔的合法構建模塊,類似 DTD。XML Schema:定義可出現在文檔中的元素定義可出現在文檔中的屬性定義哪個元素是子元素定義子元素的次序定義子元素的數目定義元素是否為空,或者是否可包含文本定義元素和屬性的數據類型定義元素和屬性的默認值以及固定值
XML Schema 是 DTD 的繼任者我們認為 XML Schema 很快會在大部分網絡應用程序中取代 DTD。理由如下:XML Schema 可針對未來的需求進行擴展XML Schema 更完善,功能更強大XML Schema 基於 XML 編寫XML Schema 支持數據類型XML Schema 支持命名空間
為什么要使用 XML Schema?
XML Schema 支持數據類型XML Schema 最重要的能力之一就是對數據類型的支持。通過對數據類型的支持:可更容易地描述允許的文檔內容可更容易地驗證數據的正確性可更容易地與來自數據庫的數據一並工作可更容易地定義數據約束(data facets)可更容易地定義數據模型(或稱數據格式)可更容易地在不同的數據類型間轉換數據
注:數據約束,或稱 facets,是 XML Schema 原型中的一個術語,中文可譯為“面”,用來約束數據類型的容許值。
XML Schema 使用 XML 語法由 XML 編寫 XML Schema 有很多好處:不必學習新的語言可使用 XML 編輯器來編輯 Schema 文件可使用 XML 解析器來解析 Schema 文件可通過 XML DOM 來處理 Schema可通過 XSLT 來轉換 Schema
XML Schema 可保護數據通信當數據從發送方被發送到接受方時,其要點是雙方應有關於內容的相同的“期望值”。通過 XML Schema,發送方可以用一種接受方能夠明白的方式來描述數據。一種數據,比如 "03-11-2004",在某些國家被解釋為11月3日,而在另一些國家為當作3月11日。但是一個帶有數據類型的 XML 元素,比如:<date type="date">2004-03-11</date>,可確保對內容一致的理解,這是因為 XML 的數據類型 "date" 要求的格式是 "YYYY-MM-DD"。
XML Schema 可擴展XML Schema 是可擴展的,因為它們由 XML 編寫。通過可擴展的 Schema 定義,您可以:在其他 Schema 中重復使用您的 Schema創建由標准類型衍生而來的您自己的數據類型在相同的文檔中引用多重的 Schema
形式良好是不夠的我們把符合 XML 語法的文檔稱為形式良好的 XML 文檔,比如:它必須以 XML 聲明開頭它必須擁有唯一的根元素開始標簽必須與結束標簽相匹配元素對大小寫敏感所有的元素都必須關閉所有的元素都必須正確地嵌套必須對特殊字符使用實體即使文檔的形式良好,仍然不能保證它們不會包含錯誤,並且這些錯誤可能會產生嚴重的后果。請考慮下面的情況:您訂購的了 5 打激光打印機,而不是 5 台。通過 XML Schema,大部分這樣的錯誤會被您的驗證軟件捕獲到。
如何使用 XSD?
XML 文檔可對 DTD 或 XML Schema 進行引用。一個簡單的 XML 文檔:請看這個名為 "note.xml" 的 XML 文檔:
<?xml version="1.0"?>
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
DTD 文件下面這個例子是名為 "note.dtd" 的 DTD 文件,它對上面那個 XML 文檔的元素進行了定義:
<!ELEMENT note (to, from, heading, body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
第 1 行定義 note 元素有四個子元素:"to, from, heading, body"。第 2-5 行定義了 to, from, heading, body 元素的類型是 "#PCDATA"。XML Schema下面這個例子是一個名為 "note.xsd" 的 XML Schema 文件,它定義了上面那個 XML 文檔的元素:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3school.com.cn"
xmlns="http://www.w3school.com.cn"
elementFormDefault="qualified">
<xs:element name="note">
<xs:complexType>
<xs:sequence>
<xs:element name="to" type="xs:string"/>
<xs:element name="from" type="xs:string"/>
<xs:element name="heading" type="xs:string"/>
<xs:element name="body" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
note 元素是一個復合類型,因為它包含其他的子元素。其他元素 (to, from, heading, body) 是簡易類型,因為它們沒有包含其他元素。對 DTD 的引用此文件包含對 DTD 的引用:
<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "http://www.w3school.com.cn/dtd/note.dtd">
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
對 XML Schema 的引用此文件包含對 XML Schema 的引用:
<?xml version="1.0"?>
<note
xmlns="http://www.w3school.com.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3school.com.cn note.xsd">
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
XSD - <schema> 元素
<schema> 元素是每一個 XML Schema 的根元素:
<?xml version="1.0"?>
<xs:schema>
...
...
</xs:schema>
<schema> 元素可包含屬性。一個 schema 聲明往往看上去類似這樣:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3school.com.cn"
xmlns="http://www.w3school.com.cn"
elementFormDefault="qualified">
...
...
</xs:schema>
代碼解釋:
xmlns:xs="http://www.w3.org/2001/XMLSchema"
顯示 schema 中用到的元素和數據類型來自命名空間 "http://www.w3.org/2001/XMLSchema"。同時它還規定了來自命名空間 "http://www.w3.org/2001/XMLSchema" 的元素和數據類型應該使用前綴 xs:
targetNamespace="http://www.w3school.com.cn"
聲明(只是聲明,並不能說明當前schema默認使用該命名空間)被此 schema 定義的元素 (note, to, from, heading, body) 屬於命名空間: "http://www.w3school.com.cn"。
xmlns="http://www.w3school.com.cn"
指出默認使用的命名空間。與targetNamespace相同,說明默認使用當前命名空間 。
elementFormDefault="qualified"
指出任何 XML 實例文檔所使用的且在此 schema 中聲明過的元素必須被命名空間限定。
<?xml version="1.0" encoding="UTF-8"?>
<sp:note xmlns:sp="http://www.w3school.com.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3school.com.cn note.xsd">
<!--note.xsd使用elementFormDefault="unqualified"-->
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</sp:note>
<?xml version="1.0" encoding="UTF-8"?>
<sp:note xmlns:sp="http://www.w3school.com.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3school.com.cn note.xsd">
<!--note.xsd使用elementFormDefault="qualified"-->
<sp:to>George</sp:to>
<sp:from>John</sp:from>
<sp:heading>Reminder</sp:heading>
<sp:body>Don't forget the meeting!</sp:body>
</sp:note>
命名空間 http://www.w3.org/2001/XMLSchema聲明的元素最終由 http://www.w3.org/2001/XMLSchema.dtd校驗
此 XML 文檔含有對 XML Schema 的引用:
<?xml version="1.0"?>
<note xmlns="http://www.w3school.com.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3school.com.cn note.xsd">
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
xmlns="http://www.w3school.com.cn"規定了默認命名空間的聲明。此聲明會告知 schema 驗證器,在此 XML 文檔中使用的所有元素都屬於 "http://www.w3school.com.cn" 這個命名空間。
一旦您擁有了可用的 XML Schema 實例命名空間:xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"您就可以使用 schemaLocation 屬性了。該屬性將具有目標命名空間的 XSD文檔與實例文檔相關聯。此屬性有兩個值: "http://www.w3school.com.cn note.xsd "第一個值是需要使用的命名空間。第二個值是供命名空間使用的 XML schema 的位置:xsi:schemaLocation="http://www.w3school.com.cn note.xsd"提供多個指定命名空間的XSD文檔的位置信息
xsi:schemaLocation=
"http://contoso.com/People
http://contoso.com/schemas/people.xsd
http://contoso.com/schemas/Vehicles
http://contoso.com/schemas/vehicles.xsd
http://contoso.com/schemas/People
http://contoso.com/schemas/people.xsd"
XSD 簡易元素
XML Schema 可定義 XML 文件的元素。簡易元素指那些只包含文本的元素。它不會包含任何其他的元素或屬性。不過,“僅包含文本”這個限定卻很容易造成誤解。文本有很多類型。它可以是 XML Schema 定義中包括的類型中的一種(布爾、字符串、數據等等),或者它也可以是您自行定義的定制類型。您也可向數據類型添加限定(即 facets),以此來限制它的內容,或者您可以要求數據匹配某種特定的模式。定義簡易元素<xs:element name="xxx" type="yyy"/>此處 xxx 指元素的名稱,yyy 指元素的數據類型。XML Schema 擁有很多內建的數據類型。最常用的類型是:xs:string xs:decimal xs:integer xs:boolean xs:date xs:time例子: 這是一些 XML 元素:
<lastname>Smith</lastname>
<age>28</age>
<dateborn>1980-03-27</dateborn>
這是相應的簡易元素定義:
<xs:element name="lastname" type="xs:string"/>
<xs:element name="age" type="xs:integer"/>
<xs:element name="dateborn" type="xs:date"/>
簡易元素的默認值和固定值簡易元素可擁有指定的默認值或固定值。當沒有其他的值被規定時,默認值就會自動分配給元素。在下面的例子中,缺省值是 "red":<xs:element name="color" type="xs:string" default="red"/>固定值同樣會自動分配給元素,並且您無法規定另外一個值。在下面的例子中,固定值是 "red":<xs:element name="color" type="xs:string" fixed="red"/>
XSD 屬性
什么是屬性?簡易元素無法擁有屬性。假如某個元素擁有屬性,它就會被當作某種復合類型。但是屬性本身總是作為簡易類型被聲明的。如何聲明屬性?定義屬性的語法是:<xs:attribute name="xxx" type="yyy"/>在此處,xxx 指屬性名稱,yyy 則規定屬性的數據類型。XML Schema 擁有很多內建的數據類型。最常用的類型是: xs:string xs:decimal xs:integer xs:boolean xs:date xs:time實例這是帶有屬性的 XML 元素:<lastname lang="EN">Smith</lastname>這是對應的屬性定義:<xs:attribute name="lang" type="xs:string"/>
屬性的默認值和固定值屬性可擁有指定的默認值或固定值。當沒有其他的值被規定時,默認值就會自動分配給元素。在下面的例子中,缺省值是 "EN":<xs:attribute name="lang" type="xs:string" default="EN"/>固定值同樣會自動分配給元素,並且您無法規定另外的值。在下面的例子中,固定值是 "EN":<xs:attribute name="lang" type="xs:string" fixed="EN"/>可選的和必需的屬性在缺省的情況下,屬性是可選的。如需規定屬性為必選,請使用 "use" 屬性:<xs:attribute name="lang" type="xs:string" use="required"/>對內容的限定當 XML 元素或屬性擁有被定義的數據類型時,就會向元素或屬性的內容添加限定。假如 XML 元素的類型是 "xs:date",而其包含的內容是類似 "Hello World" 的字符串,元素將不會(通過)驗證。
通過 XML schema,您也可向您的 XML 元素及屬性添加自己的限定。這些限定被稱為 facet(可譯為限定面)。
XSD 限定 / Facets
限定(restriction)用於為 XML 元素或者屬性定義可接受的值。對 XML 元素的限定被稱為 facet。對值的限定下面的例子定義了帶有一個限定且名為 "age" 的元素。age 的值不能低於 0 或者高於 120:
<xs:element name="age">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="120"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
對一組值的限定如需把 XML 元素的內容限制為一組可接受的值,我們要使用枚舉約束(enumeration constraint)。下面的例子定義了帶有一個限定的名為 "car" 的元素。可接受的值只有:Audi, Golf, BMW:
<xs:element name="car">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Audi"/>
<xs:enumeration value="Golf"/>
<xs:enumeration value="BMW"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
上面的例子也可以被寫為:
<xs:element name="car" type="carType"/>
<xs:simpleType name="carType">
<xs:restriction base="xs:string">
<xs:enumeration value="Audi"/>
<xs:enumeration value="Golf"/>
<xs:enumeration value="BMW"/>
</xs:restriction>
</xs:simpleType>
注釋:在這種情況下,類型 "carType" 可被其他元素使用,因為它不是 "car" 元素的組成部分。對一系列值的限定如需把 XML 元素的內容限制定義為一系列可使用的數字或字母,我們要使用模式約束(pattern constraint)。下面的例子定義了帶有一個限定的名為 "letter" 的元素。可接受的值只有小寫字母 a - z 其中的一個:
<xs:element name="letter">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[a-z]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
下一個例子定義了帶有一個限定的名為 "initials" 的元素。可接受的值是大寫字母 A - Z 其中的三個:
<xs:element name="initials">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z][A-Z][A-Z]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
下一個例子也定義了帶有一個限定的名為 "initials" 的元素。可接受的值是大寫或小寫字母 a - z 其中的三個:
<xs:element name="initials">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[a-zA-Z][a-zA-Z][a-zA-Z]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
下一個例子定義了帶有一個限定的名為 "choice 的元素。可接受的值是字母 x, y 或 z 中的一個:
<xs:element name="choice">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[xyz]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
下一個例子定義了帶有一個限定的名為 "prodid" 的元素。可接受的值是五個阿拉伯數字的一個序列,且每個數字的范圍是 0-9:
<xs:element name="prodid">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:pattern value="[0-9][0-9][0-9][0-9][0-9]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
對一系列值的其他限定下面的例子定義了帶有一個限定的名為 "letter" 的元素。可接受的值是 a - z 中零個或多個字母:
<xs:element name="letter">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="([a-z])*"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
下面的例子定義了帶有一個限定的名為 "letter" 的元素。可接受的值是一對或多對字母,每對字母由一個小寫字母后跟一個大寫字母組成。舉個例子,"sToP"將會通過這種模式的驗證,但是 "Stop"、"STOP" 或者 "stop" 無法通過驗證:
<xs:element name="letter">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="([a-z][A-Z])+"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
下面的例子定義了帶有一個限定的名為 "gender" 的元素。可接受的值是 male 或者 female:
<xs:element name="gender">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="male|female"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
下面的例子定義了帶有一個限定的名為 "password" 的元素。可接受的值是由 8 個字符組成的一行字符,這些字符必須是大寫或小寫字母 a - z 亦或數字 0 - 9:
<xs:element name="password">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[a-zA-Z0-9]{8}"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
對空白字符的限定如需規定對空白字符(whitespace characters)的處理方式,我們需要使用 whiteSpace 限定。下面的例子定義了帶有一個限定的名為 "address" 的元素。這個 whiteSpace 限定被設置為 "preserve",這意味着 XML 處理器不會移除任何空白字符:
<xs:element name="address">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:whiteSpace value="preserve"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
這個例子也定義了帶有一個限定的名為 "address" 的元素。這個 whiteSpace 限定被設置為 "replace",這意味着 XML 處理器將移除所有空白字符(換行、回車、空格以及制表符):
<xs:element name="address">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:whiteSpace value="replace"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
這個例子也定義了帶有一個限定的名為 "address" 的元素。這個 whiteSpace 限定被設置為 "collapse",這意味着 XML 處理器將移除所有空白字符(換行、回車、空格以及制表符會被替換為空格,開頭和結尾的空格會被移除,而多個連續的空格會被縮減為一個單一的空格):
<xs:element name="address">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:whiteSpace value="collapse"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
對長度的限定如需限制元素中值的長度,我們需要使用 length、maxLength 以及 minLength 限定。本例定義了帶有一個限定且名為 "password" 的元素。其值必須精確到 8 個字符:
<xs:element name="password">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:length value="8"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
這個例子也定義了帶有一個限定的名為 "password" 的元素。其值最小為 5 個字符,最大為 8 個字符:
<xs:element name="password">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="5"/>
<xs:maxLength value="8"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
數據類型的限定
限定 描述 enumeration 定義可接受值的一個列表 fractionDigits 定義所允許的最大的小數位數。必須大於等於0。 length 定義所允許的字符或者列表項目的精確數目。必須大於或等於0。 maxExclusive 定義數值的上限。所允許的值必須小於此值。 maxInclusive 定義數值的上限。所允許的值必須小於或等於此值。 maxLength 定義所允許的字符或者列表項目的最大數目。必須大於或等於0。 minExclusive 定義數值的下限。所允許的值必需大於此值。 minInclusive 定義數值的下限。所允許的值必需大於或等於此值。 minLength 定義所允許的字符或者列表項目的最小數目。必須大於或等於0。 pattern 定義可接受的字符的精確序列。 totalDigits 定義所允許的阿拉伯數字的精確位數。必須大於0。 whiteSpace 定義空白字符(換行、回車、空格以及制表符)的處理方式。
XSD 復合元素
什么是復合元素?復合元素指包含其他元素及/或屬性的 XML 元素。有四種類型的復合元素:空元素包含其他元素的元素僅包含文本的元素包含元素和文本的元素注釋:上述元素均可包含屬性!
復合元素的例子復合元素,"product",是空的:<product pid="1345"/>復合元素,"employee",僅包含其他元素:
<employee>
<firstname>John</firstname>
<lastname>Smith</lastname>
</employee>
復合元素,"food",僅包含文本:<food type="dessert">Ice cream</food>復合元素,"description",包含元素和文本:
<description>
It happened on <date lang="norwegian">03.03.99</date> ....
</description>
如何定義復合元素?請看這個復合 XML 元素,"employee",僅包含其他元素:
<employee>
<firstname>John</firstname>
<lastname>Smith</lastname>
</employee>
在 XML Schema 中,我們有兩種方式來定義復合元素:1. 通過命名此元素,可直接對"employee"元素進行聲明 ,就像這樣:
<xs:element name="employee">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
假如您使用上面所描述的方法,那么僅有 "employee" 可使用所規定的復合類型。請注意其子元素,"firstname" 以及 "lastname",被包圍在指示器 <sequence>中。這意味着子元素必須以它們被聲明的次序出現。2. "employee" 元素可以使用 type 屬性,這個屬性的作用是引用要使用的復合類型的名稱 :
<xs:element name="employee" type="personinfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
如果您使用了上面所描述的方法,那么若干元素均可以使用相同的復合類型,比如這樣:
<xs:element name="employee" type="personinfo"/>
<xs:element name="student" type="personinfo"/>
<xs:element name="member" type="personinfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
您也可以在已有的復合元素之上以某個復合元素為基礎,然后添加一些元素,就像這樣:
<xs:element name="employee" type="fullpersoninfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="fullpersoninfo">
<xs:complexContent>
<xs:extension base="personinfo">
<xs:sequence>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
XSD 復合空元素
空的復合元素不能包含內容,只能含有屬性。復合空元素:一個空的 XML 元素:<product prodid="1345" />上面的 "product" 元素根本沒有內容。為了定義無內容的類型,我們就必須聲明一個在其內容中只能包含元素的類型,但是實際上我們並不會聲明任何元素,比如這樣:
<xs:element name="product">
<xs:complexType>
<xs:complexContent>
<xs:restriction base="xs:integer">
<xs:attribute name="prodid" type="xs:positiveInteger"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:element>
在上面的例子中,我們定義了一個帶有復合內容的復合類型。complexContent 元素給出的信號是,我們打算限定或者拓展某個復合類型的內容模型,而 integer 限定則聲明了一個屬性但不會引入任何的元素內容。
不過,也可以更加緊湊地聲明此 "product" 元素:
<xs:element name="product">
<xs:complexType>
<xs:attribute name="prodid" type="xs:positiveInteger"/>
</xs:complexType>
</xs:element>
或者您可以為一個 complexType 元素起一個名字,然后為 "product" 元素設置一個 type 屬性並引用這個 complexType 名稱(通過使用此方法,若干個元素均可引用相同的復合類型):
<xs:element name="product" type="prodtype"/>
<xs:complexType name="prodtype">
<xs:attribute name="prodid" type="xs:positiveInteger"/>
</xs:complexType>
XSD 復合類型 - 僅含元素
“僅含元素”的復合類型元素是只能包含其他元素的元素 。復合類型僅包含元素XML 元素,"person",僅包含其他的元素:
<person>
<firstname>John</firstname>
<lastname>Smith</lastname>
</person>
您可在 schema 中這樣定義 "person" 元素:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
請留意這個 <xs:sequence>。它意味着被定義的元素必須按上面的次序出現在 "person" 元素中。或者您可以為 complexType 元素設定一個名稱,並讓 "person" 元素的 type 屬性來引用此名稱(如使用此方法,若干元素均可引用相同的復合類型):
<xs:element name="person" type="persontype"/>
<xs:complexType name="persontype">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
XSD 僅含文本復合元素
此類型僅包含簡易的內容(文本和屬性),因此我們要向此內容添加 simpleContent 元素。當使用簡易內容時,我們就必須在 simpleContent 元素內定義擴展或限定,就像這樣:
<xs:element name="某個名稱">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="basetype">
....
....
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
或者:
<xs:element name="某個名稱">
<xs:complexType>
<xs:simpleContent>
<xs:restriction base="basetype">
....
....
</xs:restriction>
</xs:simpleContent>
</xs:complexType>
</xs:element>
提示: 請使用 extension 或 restriction 元素來擴展或限制元素的基本簡易類型。這里有一個 XML 元素的例子,"shoesize",其中僅包含文本:<shoesize country="france">35</shoesize>下面這個例子聲明了一個復合類型,其內容被定義為整數值,並且 "shoesize" 元素含有名為 "country" 的屬性:
<xs:element name="shoesize">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="country" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
我們也可為 complexType 元素設定一個名稱,並讓 "shoesize" 元素的 type 屬性來引用此名稱(通過使用此方法,若干元素均可引用相同的復合類型):
<xs:element name="shoesize" type="shoetype"/>
<xs:complexType name="shoetype">
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="country" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
XSD 帶有混合內容的復合類型
混合的復合類型可包含屬性、元素以及文本。帶有混合內容的復合類型XML 元素,"letter",含有文本以及其他元素:
<letter>
Dear Mr.<name>John Smith</name>.
Your order <orderid>1032</orderid>
will be shipped on <shipdate>2001-07-13</shipdate>.
</letter>
下面這個 schema 聲明了這個 "letter" 元素:
<xs:element name="letter">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="orderid" type="xs:positiveInteger"/>
<xs:element name="shipdate" type="xs:date"/>
</xs:sequence>
</xs:complexType>
</xs:element>
注釋:為了使字符數據可以出現在 "letter" 的子元素之間,mixed 屬性必須被設置為 "true"。<xs:sequence> 標簽 (name、orderid 以及 shipdate ) 意味着被定義的元素必須依次出現在 "letter" 元素內部。我們也可以為 complexType 元素起一個名字,並讓 "letter" 元素的 type 屬性引用 complexType 的這個名稱(通過這個方法,若干元素均可引用同一個復合類型):
<xs:element name="letter" type="lettertype"/>
<xs:complexType name="lettertype" mixed="true">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="orderid" type="xs:positiveInteger"/>
<xs:element name="shipdate" type="xs:date"/>
</xs:sequence>
</xs:complexType>
XSD 復合類型指示器
通過指示器,我們可以控制在文檔中使用元素的方式。有七種指示器:Order 指示器:AllChoiceSequenceOccurrence 指示器:maxOccursminOccursGroup 指示器:Group nameattributeGroup nameOrder 指示器Order 指示器用於定義元素的順序。All 指示器<all> 指示器規定子元素可以按照任意順序出現,且每個子元素必須只出現一次:
<xs:element name="person">
<xs:complexType>
<xs:all>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:all>
</xs:complexType>
</xs:element>
注釋:當使用 <all> 指示器時,你可以把 <minOccurs> 設置為 0 或者 1,而只能把 <maxOccurs> 指示器設置為 1(稍后將講解 <minOccurs> 以及 <maxOccurs>)。Choice 指示器<choice> 指示器規定可出現某個子元素或者可出現另外一個子元素(非此即彼):
<xs:element name="person">
<xs:complexType>
<xs:choice>
<xs:element name="employee" type="employee"/>
<xs:element name="member" type="member"/>
</xs:choice>
</xs:complexType>
</xs:element>
提示:如需設置子元素出現任意次數,可將 <maxOccurs> (稍后會講解)設置為 unbounded(無限次)。Sequence 指示器<sequence> 規定子元素必須按照特定的順序出現:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Occurrence 指示器Occurrence 指示器用於定義某個元素出現的頻率。注釋:對於所有的 "Order" 和 "Group" 指示器(any、all、choice、sequence、group name 以及 group reference),其中的 maxOccurs 以及 minOccurs 的默認值均為 1。maxOccurs 指示器<maxOccurs> 指示器可規定某個元素可出現的最大次數:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="full_name" type="xs:string"/>
<xs:element name="child_name" type="xs:string" maxOccurs="10"/>
</xs:sequence>
</xs:complexType>
</xs:element>
上面的例子表明,子元素 "child_name" 可在 "person" 元素中最少出現一次(其中 minOccurs 的默認值是 1),最多出現 10 次。minOccurs 指示器<minOccurs> 指示器可規定某個元素能夠出現的最小次數:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="full_name" type="xs:string"/>
<xs:element name="child_name" type="xs:string"
maxOccurs="10" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
上面的例子表明,子元素 "child_name" 可在 "person" 元素中出現最少 0 次,最多出現 10 次。提示:如需使某個元素的出現次數不受限制,請使用 maxOccurs="unbounded" 這個聲明:一個實際的例子:名為 "Myfamily.xml" 的 XML 文件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<persons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="family.xsd">
<person>
<full_name>Tony Smith</full_name>
<child_name>Cecilie</child_name>
</person>
<person>
<full_name>David Smith</full_name>
<child_name>Jogn</child_name>
<child_name>mike</child_name>
<child_name>kyle</child_name>
<child_name>mary</child_name>
</person>
<person>
<full_name>Michael Smith</full_name>
</person>
</persons>
上面這個 XML 文件含有一個名為 "persons" 的根元素。在這個根元素內部,我們定義了三個 "person" 元素。每個 "person" 元素必須含有一個 "full_name" 元素,同時它可以包含多至 5 個 "child_name" 元素。這是schema文件"family.xsd":
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="persons">
<xs:complexType>
<xs:sequence>
<xs:element name="person" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="full_name" type="xs:string"/>
<xs:element name="child_name" type="xs:string"
minOccurs="0" maxOccurs="5"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Group 指示器Group 指示器用於定義相關的數批元素。元素組元素組通過 group 聲明進行定義:
<xs:group name="組名稱">
...
</xs:group>
您必須在 group 聲明內部定義一個 all、choice 或者 sequence 元素。下面這個例子定義了名為 "persongroup" 的 group,它定義了必須按照精確的順序出現的一組元素:
<xs:group name="persongroup">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="birthday" type="xs:date"/>
</xs:sequence>
</xs:group>
在您把 group 定義完畢以后,就可以在另一個定義中引用它了:
<xs:group name="persongroup">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="birthday" type="xs:date"/>
</xs:sequence>
</xs:group>
<xs:element name="person" type="personinfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:group ref="persongroup"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
屬性組屬性組通過 attributeGroup 聲明來進行定義:
<xs:attributeGroup name="組名稱">
...
</xs:attributeGroup>
下面這個例子定義了名為 "personattrgroup" 的一個屬性組:
<xs:attributeGroup name="personattrgroup">
<xs:attribute name="firstname" type="xs:string"/>
<xs:attribute name="lastname" type="xs:string"/>
<xs:attribute name="birthday" type="xs:date"/>
</xs:attributeGroup>
在您已定義完畢屬性組之后,就可以在另一個定義中引用它了,就像這樣:
<xs:attributeGroup name="personattrgroup">
<xs:attribute name="firstname" type="xs:string"/>
<xs:attribute name="lastname" type="xs:string"/>
<xs:attribute name="birthday" type="xs:date"/>
</xs:attributeGroup>
<xs:element name="person">
<xs:complexType>
<xs:attributeGroup ref="personattrgroup"/>
</xs:complexType>
</xs:element>
XSD <any> 元素
<any> 元素使我們有能力通過未被 schema 規定的元素來拓展 XML 文檔!下面這個例子是從名為 "family.xsd" 的 XML schema 中引用的片段。它展示了一個針對 "person" 元素的聲明。通過使用 <any> 元素,我們可以通過任何元素(在 <lastname> 之后)擴展 "person" 的內容:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:any minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
現在,我們希望使用 "children" 元素來擴展 "person" 元素。這此種情況下我們就可以這么做,即使以上這個 schema 的沒有聲明任何 "children" 元素。請看這個 schema 文件,名為 "children.xsd":
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3school.com.cn"
xmlns="http://www.w3school.com.cn"
elementFormDefault="qualified">
<xs:element name="children">
<xs:complexType>
<xs:sequence>
<xs:element name="childname" type="xs:string"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
下面這個 XML 文件(名為 "Myfamily.xml"),使用了來自兩個不同的 schema 中的成分,"family.xsd" 和 "children.xsd":
<?xml version="1.0" encoding="ISO-8859-1"?>
<persons xmlns="http://www.microsoft.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:SchemaLocation="http://www.microsoft.com family.xsd
http://www.w3school.com.cn children.xsd">
<person>
<firstname>David</firstname>
<lastname>Smith</lastname>
<children>
<childname>mike</childname>
</children>
</person>
<person>
<firstname>Tony</firstname>
<lastname>Smith</lastname>
</person>
</persons>
上面這個 XML 文件是有效的,這是由於 schema "family.xsd" 允許我們通過在 "lastname" 元素后的可選元素來擴展 "person" 元素。<any> 和 <anyAttribute> 均可用於制作可擴展的文檔!它們使文檔有能力包含未在主 XML schema 中聲明過的附加元素。
XSD <anyAttribute> 元素
<anyAttribute> 元素使我們有能力通過未被 schema 規定的屬性來擴展 XML 文檔!下面的例子是來自名為 "family.xsd" 的 XML schema 的一個片段。它為我們展示了針對 "person" 元素的一個聲明。通過使用 <anyAttribute> 元素,我們就可以向 "person" 元素添加任意數量的屬性:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
<xs:anyAttribute/>
</xs:complexType>
</xs:element>
現在,我們希望通過 "gender" 屬性來擴展 "person" 元素。在這種情況下我們就可以這樣做,即使這個 schema 的作者從未聲明過任何 "gender" 屬性。請看這個 schema 文件,名為 "attribute.xsd":
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3school.com.cn"
xmlns="http://www.w3school.com.cn"
elementFormDefault="qualified">
<xs:attribute name="gender">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="male|female"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:schema>
下面這個 XML(名為 "Myfamily.xml"),使用了來自不同 schema 的成分,"family.xsd" 和 "attribute.xsd":
<?xml version="1.0" encoding="ISO-8859-1"?>
<persons xmlns="http://www.microsoft.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:SchemaLocation="http://www.microsoft.com family.xsd
http://www.w3school.com.cn attribute.xsd">
<person gender="female">
<firstname>Jane</firstname>
<lastname>Smith</lastname>
</person>
<person gender="male">
<firstname>David</firstname>
<lastname>Smith</lastname>
</person>
</persons>
上面這個 XML 文件是有效的,這是因為 schema "family.xsd" 允許我們向 "person" 元素添加屬性。<any> 和 <anyAttribute> 均可用於制作可擴展的文檔!它們使文檔有能力包含未在主 XML schema 中聲明過的附加元素。
XSD 元素替換(Element Substitution)
通過 XML Schema,一個元素可對另一個元素進行替換。元素替換讓我們舉例說明:我們的用戶來自英國和挪威。我們希望有能力讓用戶選擇在 XML 文檔中使用挪威語的元素名稱還是英語的元素名稱。為了解決這個問題,我們可以在 XML schema 中定義一個 substitutionGroup。首先,我們聲明主元素,然后我們會聲明次元素,這些次元素可聲明它們能夠替換主元素。
<xs:element name="name" type="xs:string"/>
<xs:element name="navn" substitutionGroup="name"/>
在上面的例子中,"name" 元素是主元素,而 "navn" 元素可替代 "name" 元素。請看一個 XML schema 的片段:
<xs:element name="name" type="xs:string"/>
<xs:element name="navn" substitutionGroup="name"/>
<xs:complexType name="custinfo">
<xs:sequence>
<xs:element ref="name"/>
</xs:sequence>
</xs:complexType>
<xs:element name="customer" type="custinfo"/>
<xs:element name="kunde" substitutionGroup="customer"/>
有效的 XML 文檔類似這樣(根據上面的 schema):
<customer>
<name>John Smith</name>
</customer>
或類似這樣:
<kunde>
<navn>John Smith</navn>
</kunde>
阻止元素替換為防止其他的元素替換某個指定的元素,請使用 block 屬性:<xs:element name="name" type="xs:string" block="substitution"/>請看某個 XML schema 的片段:
<xs:element name="name" type="xs:string" block="substitution"/>
<xs:element name="navn" substitutionGroup="name"/>
<xs:complexType name="custinfo">
<xs:sequence>
<xs:element ref="name"/>
</xs:sequence>
</xs:complexType>
<xs:element name="customer" type="custinfo" block="substitution"/>
<xs:element name="kunde" substitutionGroup="customer"/>
合法的 XML 文檔應該類似這樣(根據上面的 schema):
<customer>
<name>John Smith</name>
</customer>
但是下面的文檔不再合法:
<kunde>
<navn>John Smith</navn>
</kunde>
使用 substitutionGroup可替換元素的類型必須和主元素相同,或者從主元素衍生而來。假如可替換元素的類型與主元素的類型相同,那么您就不必規定可替換元素的類型了。請注意, substitutionGroup 中的所有元素(主元素和可替換元素)必須被聲明為全局元素,否則就無法工作!什么是全局元素(Global Elements)?全局元素指 "schema" 元素的直接子元素!本地元素(Local elements)指嵌套在其他元素中的元素。
一個 XSD 實例
本節會為您演示如何編寫一個 XML Schema。您還將學習到編寫 schema 的不同方法。XML 文檔讓我們看看這個名為 "shiporder.xml" 的 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 文檔創建一個 schema。我們可以通過打開一個新的文件來開始,並把這個文件命名為 "shiporder.xsd"。要創建schema,我們僅僅需要簡單地遵循 XML 文檔中的結構,定義我們所發現的每個元素。首先我們開始定義一個標准的 XML 聲明:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
...
</xs:schema>
在上面的 schema 中,我們使用了標准的命名空間 (xs),與此命名空間相關聯的 URI 是 Schema 的語言定義(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) 的前綴是由命名空間的前綴規定的,此命名空間與指示預定義的 schema 數據類型的 XML 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 屬性設定為 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>
使用指定的類型(Named Types)第三種設計方法定義了類或者類型,這樣使我們有能力重復使用元素的定義。具體的方式是:首先對簡易元素和復合元素進行命名,然后通過元素的 type 屬性來指向它們。這是利用第三種方法設計的 schema 文件 ("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 的數字。
XSD 字符串數據類型
字符串數據類型用於可包含字符串的值。字符串數據類型(String Data Type)字符串數據類型可包含字符、換行、回車以及制表符。下面是一個關於某個 scheme 中字符串聲明的例子:<xs:element name="customer" type="xs:string"/>文檔中的元素看上去應該類似這樣:<customer>John Smith</customer>或者類似這樣:<customer> John Smith </customer>注釋:如果您使用字符串數據類型,XML 處理器就不會更改其中的值。規格化字符串數據類型(NormalizedString Data Type)規格化字符串數據類型源自於字符串數據類型。規格化字符串數據類型同樣可包含字符,但是 XML 處理器會移除折行,回車以及制表符。下面是一個關於在某個 schema 中規格化字符串數據類型的例子:<xs:element name="customer" type="xs:normalizedString"/>文檔中的元素看上去應該類似這樣:<customer>John Smith</customer>或者類似這樣:<customer> John Smith </customer>注釋:在上面的例子中,XML 處理器會使用空格替換所有的制表符。Token 數據類型(Token Data Type)Token 數據類型同樣源自於字符串數據類型。Token 數據類型同樣可包含字符,但是 XML 處理器會移除換行符、回車、制表符、開頭和結尾的空格以及(連續的)空格。下面是在 schema 中一個有關 token 聲明的例子:<xs:element name="customer" type="xs:token"/>文檔中的元素看上去應該類似這樣:<customer>John Smith</customer>或者類似這樣:<customer> John Smith </customer>注釋:在上面這個例子中,XML 解析器會移除制表符。字符串數據類型請注意,所有以下的數據類型均衍生於字符串數據類型(除了字符串數據類型本身)!
名稱 描述 ENTITIES ENTITY 實體類型 ID 在 XML 中提交 ID 屬性的字符串 (僅與 schema 屬性一同使用) IDREF 在 XML 中提交 IDREF 屬性的字符串(僅與 schema 屬性一同使用) IDREFS language 包含合法的語言 id 的字符串 Name 包含合法 XML 名稱的字符串 NCName NMTOKEN 在 XML 中提交 NMTOKEN 屬性的字符串 (僅與 schema 屬性一同使用) NMTOKENS normalizedString 不包含換行符、回車或制表符的字符串 QName string 字符串 token 不包含換行符、回車或制表符、開頭或結尾空格或者多個連續空格的字符串 對字符串數據類型的限定(Restriction)可與字符串數據類型一同使用的限定:enumerationlengthmaxLengthminLengthpattern (NMTOKENS、IDREFS 以及 ENTITIES 無法使用此約束)whiteSpace
XSD 日期及時間數據類型(Date and Time Data Types)
日期及時間數據類型用於包含日期和時間的值。日期數據類型(Date Data Type)日期數據類型用於定義日期。日期使用此格式進行定義:"YYYY-MM-DD",其中:YYYY 表示年份MM 表示月份DD 表示天數注釋:所有的成分都是必需的!下面是一個有關 schema 中日期聲明的例子:<xs:element name="start" type="xs:date"/>文檔中的元素看上去應該類似這樣:<start>2002-09-24</start>時區如需規定一個時區,您也可以通過在日期后加一個 "Z" 的方式,使用世界調整時間(UTC time)來輸入一個日期 - 比如這樣:<start>2002-09-24Z</start>或者也可以通過在日期后添加一個正的或負時間的方法,來規定以世界調整時間為准的偏移量 - 比如這樣:<start>2002-09-24-06:00</start>或者:<start>2002-09-24+06:00</start>時間數據類型(Time Data Type)時間數據類型用於定義時間。時間使用下面的格式來定義:"hh:mm:ss",其中hh 表示小時mm 表示分鍾ss 表示秒注釋:所有的成分都是必需的!下面是一個有關 schema 中時間聲明的例子:<xs:element name="start" type="xs:time"/>文檔中的元素看上去應該類似這樣:<start>09:00:00</start>或者類似這樣:<start>09:30:10.5</start>時區如需規定一個時區,您也可以通過在時間后加一個 "Z" 的方式,使用世界調整時間(UTC time)來輸入一個時間 - 比如這樣:<start>09:30:10Z</start>或者也可以通過在時間后添加一個正的或負時間的方法,來規定以世界調整時間為准的偏移量 - 比如這樣:<start>09:30:10-06:00</start>或者:<start>09:30:10+06:00</start>日期時間數據類型(DateTime Data Type)日期時間數據類型用於定義日期和時間。日期時間使用下面的格式進行定義:"YYYY-MM-DDThh:mm:ss",其中:YYYY 表示年份MM 表示月份DD 表示日T 表示必需的時間部分的起始hh 表示小時mm 表示分鍾ss 表示秒注釋:所有的成分都是必需的!下面是一個有關 schema 中日期時間聲明的例子:<xs:element name="startdate" type="xs:dateTime"/>文檔中的元素看上去應該類似這樣:<startdate>2002-05-30T09:00:00</startdate>或者類似這樣:<startdate>2002-05-30T09:30:10.5</startdate>時區如需規定一個時區,您也可以通過在日期時間后加一個 "Z" 的方式,使用世界調整時間(UTC time)來輸入一個日期時間 - 比如這樣:<startdate>2002-05-30T09:30:10Z</startdate>或者也可以通過在時間后添加一個正的或負時間的方法,來規定以世界調整時間為准的偏移量 - 比如這樣:<startdate>2002-05-30T09:30:10-06:00</startdate>或者:<startdate>2002-05-30T09:30:10+06:00</startdate>持續時間數據類型(Duration Data Type)持續時間數據類型用於規定時間間隔。時間間隔使用下面的格式來規定:"PnYnMnDTnHnMnS",其中:P 表示周期(必需)nY 表示年數nM 表示月數nD 表示天數T 表示時間部分的起始 (如果您打算規定小時、分鍾和秒,則此選項為必需)nH 表示小時數nM 表示分鍾數nS 表示秒數下面是一個有關 schema 中持續時間聲明的例子:<xs:element name="period" type="xs:duration"/>文檔中的元素看上去應該類似這樣:<period>P5Y</period>上面的例子表示一個 5 年的周期。或者類似這樣:<period>P5Y2M10D</period>上面的例子表示一個 5 年、2 個月及 10 天的周期。或者類似這樣:<period>P5Y2M10DT15H</period>上面的例子表示一個 5 年、2 個月、10 天及 15 小時的周期。或者類似這樣:<period>PT15H</period>上面的例子表示一個 15 小時的周期。負的持續時間如需規定一個負的持續時間,請在 P 之前輸入減號:<period>-P10D</period>上面的例子表示一個負 10 天的周期。日期和時間數據類型
名稱 描述 date 定義一個日期值 dateTime 定義一個日期和時間值 duration 定義一個時間間隔 gDay 定義日期的一個部分 - 天 (DD) gMonth 定義日期的一個部分 - 月 (MM) gMonthDay 定義日期的一個部分 - 月和天 (MM-DD) gYear 定義日期的一個部分 - 年 (YYYY) gYearMonth 定義日期的一個部分 - 年和月 (YYYY-MM) time 定義一個時間值 對日期數據類型的限定(Restriction)可與日期數據類型一同使用的限定:enumerationmaxExclusivemaxInclusiveminExclusiveminInclusivepatternwhiteSpace
XSD 數值數據類型(Numeric Data Types)
十進制數據類型用於規定一個數值。下面是一個關於某個 scheme 中十進制數聲明的例子。<xs:element name="prize" type="xs:decimal"/>文檔中的元素看上去應該類似這樣:<prize>999.50</prize>或者類似這樣:<prize>+999.5450</prize>或者類似這樣:<prize>-999.5230</prize>或者類似這樣:<prize>0</prize>或者類似這樣:<prize>14</prize>注釋:您可規定的十進制數字的最大位數是 18 位。整數數據類型整數數據類型用於規定無小數成分的數值。下面是一個關於某個 scheme 中整數聲明的例子。<xs:element name="prize" type="xs:integer"/>文檔中的元素看上去應該類似這樣:<prize>999</prize>或者類似這樣:<prize>+999</prize>或者類似這樣:<prize>-999</prize>或者類似這樣:<prize>0</prize>數值數據類型請注意,下面所有的數據類型均源自於十進制數據類型(除 decimal 本身以外)!
名字 秒數 byte 有正負的 8 位整數,表示整型數,大小介於-128和127之間 decimal 十進制數 int 有正負的 32 位整數,表示整型數,大小介於-2147483648和 2147483647之間 integer 整數值 long 有正負的 64 位整數,表示整型數,大小介於-9223372036854775808和9223372036854775807之間 negativeInteger 僅包含負值的整數 ( .., -2, -1.) nonNegativeInteger 僅包含非負值的整數 (0, 1, 2, ..) nonPositiveInteger 僅包含非正值的整數 (.., -2, -1, 0) positiveInteger 僅包含正值的整數 (1, 2, ..) short 有正負的 16 位整數,表示整型數,大小介於-32768和32767之間 unsignedLong 無正負的 64 位整數 unsignedInt 無正負的 32 位整數 unsignedShort 無正負的 16 位整數 unsignedByte 無正負的 8 位整數 對數值數據類型的限定(Restriction)可與數值數據類型一同使用的限定:enumerationfractionDigitsmaxExclusivemaxInclusiveminExclusiveminInclusivepatterntotalDigitswhiteSpace
XSD 雜項數據類型(Miscellaneous Data Types)
其他雜項數據類型包括邏輯、base64Binary、十六進制、浮點、雙精度、anyURI、anyURI 以及 NOTATION。邏輯數據類型(Boolean Data Type)邏輯數據性用於規定 true 或 false 值。下面是一個關於某個 scheme 中邏輯聲明的例子:<xs:attribute name="disabled" type="xs:boolean"/>文檔中的元素看上去應該類似這樣:<prize disabled="true">999</prize>注釋:合法的布爾值是 true、false、1(表示 true) 以及 0(表示 false)。二進制數據類型(Binary Data Types)二進制數據類型用於表達二進制形式的數據。我們可使用兩種二進制數據類型:base64Binary (Base64 編碼的二進制數據)hexBinary (十六進制編碼的二進制數據)下面是一個關於某個 scheme 中 hexBinary 聲明的例子:<xs:element name="blobsrc" type="xs:hexBinary"/>AnyURI 數據類型(AnyURI Data Type)anyURI 數據類型用於規定 URI。下面是一個關於某個 scheme 中 anyURI 聲明的例子:<xs:attribute name="src" type="xs:anyURI"/>文檔中的元素看上去應該類似這樣:<pic src="http://www.w3school.com.cn/images/smiley.gif" />注釋:假如某個 URI 含有空格,請用 %20 替換它們。雜項數據類型(Miscellaneous Data Types)
名稱 描述 anyURI base64Binary boolean double float hexBinary NOTATION QName 對雜項數據類型的限定(Restriction)可與雜項數據類型一同使用的限定:enumeration (布爾數據類型無法使用此約束*)length (布爾數據類型無法使用此約束)maxLength (布爾數據類型無法使用此約束)minLength (布爾數據類型無法使用此約束)patternwhiteSpace*譯者注:約束指 constraint。
XML Schema list 元素
list 元素定義單個 simpleType 定義的集合。該屬性把簡單類型定義為指定數據類型的值的一個列表。下面的例子展示了為一列整數的簡單類型:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="intvalues" type="valuelist">
<xs:simpleType name="valuelist">
<xs:list itemType="xs:integer"/>
</xs:simpleType>
</xs:schema>
文檔中的 "intvalues" 元素類似這樣(注意這個列表有五個列表項):<intvalues>100 34 56 -23 1567</intvalues>注釋:空格被作為列表項的分隔符。
XML Schema union 元素
union 元素定義多個 simpleType 定義的集合。從一個特定簡單數據類型的集合中選擇定義一個簡單類型元素.
本例是一個合並了兩個簡單類型的簡單類型:
<xs:element name="jeans_size">
<xs:simpleType>
<xs:union memberTypes="sizebyno sizebystring" />
</xs:simpleType>
</xs:element>
<xs:simpleType name="sizebyno">
<xs:restriction base="xs:positiveInteger">
<xs:maxInclusive value="42"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="sizebystring">
<xs:restriction base="xs:string">
<xs:enumeration value="small"/>
<xs:enumeration value="medium"/>
<xs:enumeration value="large"/>
</xs:restriction>
</xs:simpleType>
XML Schema unique 元素
定義和用法
unique 元素指定屬性或元素值(或者屬性或元素值的組合)在指定范圍內必須是唯一的。 該值必須唯一或為零。
unique 元素必須按順序包含下列元素:
selector 元素
selector 元素包含 XPath 表達式,指定一個元素集,在其中由 field 元素指定的值必須唯一。
必須有一個且只有一個 selector 元素。
field 元素
每一個 field 元素均包含一個 XPath 表達式,指定對於由 selector 元素指定的元素集而言必須唯一的值(屬性或元素值)。
如果有多個 field 元素,則 field 元素的組合必須是唯一的。 在此情況下,單個 field 元素的值對於選定元素不一定是唯一的,但所有字段的組合必須是唯一的。
必須有一個或多個 field 元素
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
attributeFormDefault="unqualified" targetNamespace="http://www.test.com" xmlns:tn="http://www.test.com">
<xs:element name="books">
<xs:complexType>
<xs:sequence>
<xs:element name="book" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
<xs:attribute name="id" type="xs:integer"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="bookUnique">
<xs:selector xpath="tn:book"/>
<xs:field xpath="@id"/>
</xs:unique>
</xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<tn:books xsi:schemaLocation="http://www.test.com t.xsd" xmlns:tn="http://www.test.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<tn:book id="1">
<tn:title>a</tn:title>
<tn:price>10</tn:price>
</tn:book>
<tn:book id="2">
<tn:title>a</tn:title>
<tn:price>10</tn:price>
</tn:book>
<tn:book id="1">
<tn:title>a</tn:title>
<tn:price>10</tn:price>
</tn:book>
/tn:books>
XML Schema unique 元素
定義和用法
unique 元素指定屬性或元素值(或者屬性或元素值的組合)在指定范圍內必須是唯一的。 該值必須唯一或為零。
unique 元素必須按順序包含下列元素:
selector 元素
selector 元素包含 XPath 表達式,指定一個元素集,在其中由 field 元素指定的值必須唯一。
必須有一個且只有一個 selector 元素。
field 元素
每一個 field 元素均包含一個 XPath 表達式,指定對於由 selector 元素指定的元素集而言必須唯一的值(屬性或元素值)。
如果有多個 field 元素,則 field 元素的組合必須是唯一的。 在此情況下,單個 field 元素的值對於選定元素不一定是唯一的,但所有字段的組合必須是唯一的。
必須有一個或多個 field 元素
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
attributeFormDefault="unqualified" targetNamespace="http://www.test.com" xmlns:tn="http://www.test.com">
<xs:element name="books">
<xs:complexType>
<xs:sequence>
<xs:element name="book" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
<xs:attribute name="id" type="xs:integer"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="bookUnique">
<xs:selector xpath="tn:book"/>
<xs:field xpath="@id"/>
</xs:unique>
</xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<tn:books xsi:schemaLocation="http://www.test.com t.xsd" xmlns:tn="http://www.test.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<tn:book id="1">
<tn:title>a</tn:title>
<tn:price>10</tn:price>
</tn:book>
<tn:book id="2">
<tn:title>a</tn:title>
<tn:price>10</tn:price>
</tn:book>
<tn:book id="1">
<tn:title>a</tn:title>
<tn:price>10</tn:price>
</tn:book>
/tn:books>
問題
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
targetNamespace="http://www.test.com"
xmlns="http://www.test.com">
<xs:attribute name="fk" type="xs:integer"/>
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
</xs:sequence>
<xs:attribute name="id" type="xs:integer"/>
<xs:attribute ref="fk"/>
</xs:complexType>
</xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<book xmlns="http://www.test.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.test.com test.xsd"
id="1" fk="fk">
<title/>
</book>
