Schema詳解


XML Schema 簡介

XSD 爲什麼使用
    XML Schema 是基於 XML 的 DTD 替代者。
    XML Schema 可描述 XML 文檔的結構。
    XML Schema 語言也可做爲 XSD(XML Schema Definition)來引用。

在繼續學習以前,您須要對下面的知識有基本的瞭解:
    HTML / XHTML
    XML 以及 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"?><notexmlns="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 指示器:
    All
    Choice
    Sequence
Occurrence 指示器:
    maxOccurs
    minOccurs
Group 指示器:
    Group name
    attributeGroup name
Order 指示器
     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.xsdhttp://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.xsdhttp://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)
可與字符串數據類型一同使用的限定:
    enumeration
    length
    maxLength
    minLength
    pattern (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)
可與日期數據類型一同使用的限定:
    enumeration
    maxExclusive
    maxInclusive
    minExclusive
    minInclusive
    pattern
    whiteSpace

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)
可與數值數據類型一同使用的限定:
    enumeration
    fractionDigits
    maxExclusive
    maxInclusive
    minExclusive
    minInclusive
    pattern
    totalDigits
    whiteSpace

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 (布爾數據類型沒法使用此約束)
    pattern
    whiteSpace
*譯者注:約束指 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 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>




相關文章
相關標籤/搜索