理解XML Schema: XML Schema 初步 (I)

本文章系列是XML Schema的一個從入門到進階的基本教程。內容主要翻譯整理了W3C關於XML Schema的入門級規範:XML Schema Part 0: Primer( http://www.w3.org/TR/xmlschema-0/),同時譯者添加了一些個人的編注,並重新整理安排了章節。奉獻給大家,旨在讓更多的讀者來了解,熟悉XML Schema。

XML Schema是W3C的推薦標準,於2001年5月正式發佈,經過數年的大規模討論和開發,終於最終奠定下來,使得XML建模有了一個國際標準。XML Schema一確定下來,立刻成爲全球公認得首選XML環境下的建模工具,已經基本取代了DTD在XML剛剛成爲W3C推薦標準時的地位。由於XML是 SGML的一個子集,因此它也繼承了SGML世界中用於建模的DTD,當時使用DTD的好處是可以利用大量的在SGML世界中現有的DTD工具,使得開發 應用代價維持在一個相對較低的水平。然而,DTD有着不少缺陷:1)DTD是基於正則表達式的,描述能力有限;2) DTD沒有數據類型的支持,在大多數應用環境下能力不足;3) DTD的約束定義能力不足,無法對XML實例文檔作出更細緻的語義限制;4) DTD的結構不夠結構化,重用的代價相對較高;5)DTD並非使用XML作爲描述手段,而DTD的構建和訪問並沒有標準的編程接口,無法使用標準的編程方 式進行DTD維護。而XML Schema正是針對這些DTD的缺點而設計的,XML Schema是完全使用XML作爲描述手段,具有很強的描述能力、擴展能力和處理維護能力。

XML Schema的主要目的是用來定義一類XML文檔(一個XML Application)。因此模式的"實例文檔"形式常常用來描述一個與特定XML Schema相一致的XML文檔。事實上,文檔實例和Schema文檔都不是必須要以文檔的形式存在,他們可以存在以於應用之間傳遞的字節流的形式存在, 或者作爲一個數據庫記錄或者作爲XML的"信息項"的集合而存在。然而爲了簡化入門,我們總是把實例和模式看作文檔或者文件,認爲它們總以文檔實例或是模 式文檔的形式存在。讓我們開始考慮一個在文件po.xml中的實例文檔。它描述了一個由家庭產品採購和支付應用生成的購買訂單。

po.xml,購買訂單的XML實例文檔
<?xml version="1.0"?>
<purchaseOrder orderDate="1999-10-20">
<shipTo country="US">
<name>Alice Smith</name>
<street>123 Maple Street</street>
<city>Mill Valley</city>
<state>CA</state>
<zip>90952</zip>
</shipTo>
<billTo country="US">
<name>Robert Smith</name>
<street>8 Oak Avenue</street>
<city>Old Town</city>
<state>PA</state>
<zip>95819</zip>
</billTo>
<comment>Hurry, my lawn is going wild!</comment>
<items>
<item partNum="872-AA">
<productName>Lawnmower</productName>
<quantity>1</quantity>
<USPrice>148.95</USPrice>
<comment>Confirm this is electric</comment>
</item>
<item partNum="926-AA">
<productName>Baby Monitor</productName>
<quantity>1</quantity>
<USPrice>39.98</USPrice>
<shipDate>1999-05-21</shipDate>
</item>
</items>
</purchaseOrder>

購買訂單由一個主元素 purchaseOrder和子元素shipTo、billTo、comment和items組成。這些子元素(除了comment)也依次包括其他子元 素等等。直到一個像USPrice這樣的子元素,它包含的是一個數字而不是任何子元素。元素如果包含子元素或者是帶有屬性則被稱爲複合類型;反之元素如果 僅僅包含數字、字符串或者其他數據等,但不包含任何子元素則稱爲簡單類型。

在實例文檔中複合類型和一些簡單類型是在購買定單的模式文檔中定義。而其他一些標準的簡單類型則是作爲XML Schema內置的簡單類型的指令表的一部分定義的。

在 繼續查閱購買訂單模式文檔之前,我們暫時離題來提一下實例文檔和購買訂單模式文檔之間的聯繫。觀察實例文檔你可以看到購買訂單模式文檔並沒有被提及。一個 實例文檔實際上不需要引用模式文檔,當然儘管很多實例文檔確實引用了,爲了使這第一節簡單化,我們一開始選擇不引用。並且假設任何實例文檔的處理器即使從 實例文檔中得不到任何信息,也能夠包含購買訂單模式文檔的處理。在後面的章節,我們將介紹聯繫實例文檔和模式文檔的外部機制。

購買訂單模式文檔

購買訂單模式文檔包含在文件po.xsd中:

po.xsd,購買訂單的Schema文檔
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Purchase order schema for Example.com.
Copyright 2000 Example.com. All rights reserved.
</xsd:documentation>
</xsd:annotation>
<xsd:element name="purchaseOrder" type="PurchaseOrderType"/>
<xsd:element name="comment" type="xsd:string"/>
<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
<xsd:complexType name="USAddress">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN"
fixed="US"/>
</xsd:complexType>
<xsd:complexType name="Items">
<xsd:sequence>
<xsd:element name="item" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="productName" type="xsd:string"/>
<xsd:element name="quantity">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="USPrice" type="xsd:decimal"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="partNum" type="SKU" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<!-- Stock Keeping Unit, a code for identifying products -->
<xsd:simpleType name="SKU">
<xsd:restriction base="xsd:string">
<xsd:pattern value="/d{3}-[A-Z]{2}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

購買訂單模式文檔由一個schema元素和一系列子元素組成,大多數子元素爲element, complexType, 和simpleType,這些決定了在實例文檔中的元素的表現方式和內容。

通 過出現在schema元素中的命名空間聲明xmlns:xsd="http://www.w3.org/2001/XMLSchema",在模式文檔中的 每一個元素都有一個與XML Schema命名空間相聯繫的命名空間前綴"xsd:"。儘管任何前綴都能夠被使用,但是,前綴"xsd:"被約定用於表示XML Schema命名空間。通過使用同樣的前綴,這樣同樣的關聯也出現在內置的簡單類型的名字中。例如,xsd:string。這種形式的關聯的目的是用來標 識元素和簡單類型是屬於XML Schema語言的詞彙表而不是模式文檔作者自己的詞彙表。爲了在這裏清楚表示,我們僅提及元素的名字和簡單類型(如simpleType)而忽略了它們 的前綴"xsd:"。





回頁首


複合類型定義,元素和屬性聲明

在XML Schema中,對於允許元素有他們自己的內容以及可以攜帶自身屬性的複合類型與那些不能夠有元素內容和屬性的簡單類型之間,有着基本的不同。而在實例文 檔中,對於能建立新的類型(無論簡單和複雜)的定義和允許元素和屬性有特定的名字和類型(無論是簡單還是複雜)的聲明之間,也有着顯著的差別。在這一節 中,我們將針對如何定義複合類型,以及如何聲明使用複合類型的元素及其屬性。

新的複合類型使用 complexType元素來定義,這樣的定義典型的包含一組元素聲明,元素引用和屬性聲明。這些元素聲明與其說是它們自身的類型,不如說是一由相關模式 控制的名與控制這些名在實例文檔中的表現形式的約束之間的關聯。元素使用element元素聲明,同時屬性使用attribute來聲明。舉例來說, USAddress被定義爲一個複合類型並且在USAddress定義中我們看到五個元素的聲明和一個屬性的聲明。

<xsd:complexType name="USAddress" >
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType>

這個定義的結果將是,在實例文檔中出現的任 何類型聲明爲USAddress的元素(比如在po.xml中的shiptTo)必須包含五個元素和一個屬性。這些元素必須被命名爲name、 street、city、state和zip,這些名稱就如同在模式聲明中name屬性的值所指的那樣。並且這些屬性必須按照模式聲明中的同樣的順序出 現。前四個元素必須包含一個字符串元素內容而第五個必須包含一個十進制數字類型的元素內容。聲明爲USAddress類型的元素可以帶有一個 country屬性,該屬性必須包含字符串"US"。

USAddress類型定義僅僅包含引用簡單類型的聲明: string、decimal 和NMTOKEN。與之對比,PurchaseOrderType類型定義則包含了引用複合類型的元素聲明,如USAddress,雖然兩個類型聲明都使 用同樣的type屬性來標識類型,而無需管類型是簡單的還是複合的。

<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>

在PurchaseOrderType的類 型定義中,對於shipTo 和 billTo這兩個子元素的聲明,它們將不同的元素名字和相同的複合類型相關聯,這個複合類型是USAddress。這個定義的結果是,如果在實例文檔中 出現的任何元素(如po.xml中),當元素類型被聲明爲PurchaseOrderType時,那麼這個元素必須包含兩個名爲shipTo 和billTo的元素,這兩個元素都要包含五個子元素(name、street、city、state和zip),這五個子元素是作爲USAddress 聲明的一部分而出現的。應USAddress的相關類型定義,shipTo和billTo元素也可以包含country屬性。

PurchaseOrderType 類型定義包含了一個orderDate屬性聲明,就像在UAAddress中的country屬性聲明一樣,它被標識爲一個簡單類型,實際上,所有的屬性 聲明必須引用簡單類型。這是因爲不像元素聲明,屬性不能包含其他元素或者其他屬性。迄今爲止我們描述的元素聲明對於每一個名字都和一個現存的類型定義相關 聯。然而有時候,使用一個現存的元素比定義一個新的元素更方便。

<xsd:element ref="comment" minOccurs="0"/>

這個聲明定義引用了一個現存的元素 comment,該元素在購買訂單模式文檔中的其他地方有定義。一般的來說,ref屬性的值必須指向一個全局元素,一般來說,應當是在下面聲明的而不是作 爲複合類型定義的一部分聲明的。這個聲明的結果爲一個叫comment的元素可以出現在實例文檔的關於這個定義的相關部分中,他的內容必須和那個被引用的 元素的類型一致,在這個情況下是" string"。





回頁首


出現約束

我 們看到,在前面中的元素聲明中minOccurs屬性的值爲0 ,所以comment元素在PurchaseOrderType類型中是一個可選項。一般的來說,當minOccurs的值爲1或者更多時,一個元素就必 須出現。一個元素可以出現的最大數量由聲明中的maxOccurs屬性所決定的。這個值也許是一個正的整型如41,或者以"unbounded"的形式來 表明不限最大的出現數量。minOccurs和maxOccurs屬性的默認值是1。因此,當一個元素如comment,沒有定義maxOccurs屬 性,元素不可以出現超過一次。如果你僅僅指定了minOccurs屬性的值,它必須小於等於maxOccurs的默認值,也就是說minOccurs如果 單獨出現,其取值只能爲0或者1。同樣的,如果你只指定了maxOccurs屬性,它必須大於等於minOccurs的默認值,也就是必須取值爲1或者更 多。如果兩個屬性都被省略了,那麼元素必須出現且僅出現一次。

而對於屬性而言,它可以出現一次或者更本不出現,不會有其他的出現次數,所以指定屬性出現次數的語法與元素的語法有所不同。特別的,屬性聲明能夠使用一個use屬性來指明屬性是否需要出現(參閱po.xsd中partNum屬性的聲明)。

屬 性和元素的默認值都是使用default屬性來聲明,不過這個屬性在不同的情況下有些許不同的語義表示結果。當一個屬性使用默認值來聲明的時候,如果屬性 在實例文檔中出現了,那麼屬性的值就是屬性在實例文檔中出現的那個值。如果屬性沒有在實例文檔中出現,模式 處理器將認爲這個屬性的值等於聲明中default屬性的值。需要注意的是,屬性默認值只在屬性本身爲"可選的"時候纔有意義,如果在聲明中,即指定了默 認值,同時又設置了use屬性爲除"optional"以外的其他值的話,處理器就會產生錯誤。

而當一個元素聲 明中有默認值定義的時候,模式處理器在處理默認的元素值的時候,與處理屬性的默認值相比有一些不同。如果實例文檔中元素出現且帶有自身的內容的時候,元素 的值就是是實例文檔中元素的內容,如果元素沒有內容,那麼模式處理器就認爲這個元素的值(內容)等於聲明中default屬性的值。然而,如果元素在實例 文檔中並不出現,模式處理器則更本不認爲該元素出現。總而言之,元素和屬性默認值之間的區別可以認爲是:當屬性不出現時默認的屬性值被應用,當元素內容爲 空的時候,默認的元素值被應用。

屬性和元素聲明中都使用到fixed屬性來確保屬性和元素被設置爲特殊的值,如 po.xsd中包含了一個country屬性的聲明,這個country屬性聲明就有一個fixed屬性,值爲US。這個聲明意味着在實例文檔中 country屬性的出現是可選的(use屬性的默認值是optional),但是如果屬性出現,他的值必須爲"US",如果屬性不出現,模式處理器將自 動設置country屬性值爲"US"。需要注意的是,fixed值的概念和default值的概念是互斥的。所以如果同時聲明fixed和 default屬性就會令模式處理器產生一個錯誤。

在元素和屬性聲明中用於約束他們出現行爲的屬性的值被概括地羅列在下表中:

元素 - 使用(minOccurs, maxOccurs) fixed, default 屬性 - 使用use, fixed, default 註解
(1, 1) -, - required, -, - 元素/屬性必須出現一次,它可以有任何值。
(1, 1) 37, - Required, 37, - 元素屬性必須出現一次,他的值爲37。
(2, unbounded) 37, - 無相關描述 元素必須出現兩次或者多次,他的值必須爲37,一般說來,minOccurs 和maxOccurs可以爲正數,maxOccurs可以爲"unbounded"。
(0, 1) -, - optional, -, - 元素/屬性可以出現一次,他可以有任何值。
(0, 1) 37, - optional, 37, - 元素/屬性可以出現一次,如果出現他的值必須爲37,如果不出現他的值爲37。
(0, 1) -, 37 optional, -, 37 元素/屬性可以出現一次,如果不出現值爲37,否則他的值爲給出的值。
(0, 2) -, 37 無相關描述 元素可以出現一次、兩次或者更本不出現,如果元素不出現,則默認值不發生作用,如果出現並且他爲空元素,則其值爲37,否則值爲實例中給出的值。一般說來,minOccurs 和maxOccurs可以爲正數,maxOccurs可以爲"unbounded"。
(0, 0) -, - prohibited, -, - 元素/屬性必須不出現。

在這裏,值得注意的是,在全局的元素和屬性聲明中,minOccurs、maxOccurs、use都沒有出現。





回頁首


全局元素和屬性

全 局的元素和全局的屬性是在全局聲明時被建立的,全局聲明都是作爲元素的子元素出現的。一旦經過定義,全局元素或者全局屬性可以像先前我們描述的那樣使用 ref屬性在一個或多個聲明中引用。一個引用全局元素的聲明,允許被引用的元素在實例文檔中出現在引用這個元素的聲明相關的元素中。所以,舉例來說, po.xml中的comment元素同樣可以在shipTo、billTo和items元素中出現,因爲引用comment的複合類型定義的聲明同樣出現 在這三個元素的聲明中。

一個全局元素的聲明也允許元素在實例文檔中以頂級的文檔元素出現,因此 purchaseOrder元素,在po.xsd中是作爲一個全局元素聲明的,能夠作爲po.xml.中的頂級元素出現。值得注意的是,基於這個基本原 理, comment元素作爲頂級元素出現在文檔如po.xml中也是被允許的。

關於使用全局的元素和屬性有很 多忠告,其中一個忠告是全局的聲明不能夠包含引用。全局的聲明定義不能包含ref 屬性,他們必須使用type 屬性(或者,像我們簡短描述的,跟隨一個匿名的類型的定義)。第二個忠告是約束不能夠放在全局聲明中。儘管他們能夠放在引用全局聲明的局部聲明中。換句話 說,全局聲明不能夠包含minOccurs、maxOccurs、或者use屬性。





回頁首


命名衝突

我 們現在已經討論瞭如何定義新的複合類型(比如PurchaseOrderType),聲明元素(比如purchaseOrder)和聲明屬性(如 orderDate)。這些行爲一般都包含着命名,因此,問題自然就出現了:如果我們給兩個對象賦予同樣的名稱會如何?答案取決於問題中的兩個對象,盡 管,一般來說兩個對象越相近,他們越有可能引起衝突。

這裏有一些例子來說明什麼時候同樣的名稱會導致問題的出 現。如果兩個對象都是類型,如果我們去定義了一個複合類型稱爲USStates,同時又定義了一個簡單類型稱爲USStates,此時就出現了衝突。如果 兩個對象是類型和元素或者是類型或者屬性,當我們定義了一個複合類型叫USAddress,同時我們又定義了一個元素稱爲USAddress,此時是沒有 衝突發生的。如果兩個對象是不同類型的元素(一般的,並非是全局元素),當我們聲明瞭一個元素名字作爲USAddress類型的一部分並且第二個元素名字 作爲item類型的一部分,此時就沒有衝突(類似的元素有時候稱爲局部元素聲明)。最後,如果兩個對象都是類型,你自己定義了其中的一個,而XML Schema規範內置定義了另外的一個,比如你自己定義了一個簡單類型稱爲decimal,那麼此時沒有衝突發生。最後一個例子中之所以沒有命名衝突發生 的原因是,因爲他們屬於不同的命名空間,我們將在後討論在XML Schema中的XML命名空間的使用。





回頁首


簡單類型

在 購買訂單模式文檔中,幾個元素和屬性被聲明爲簡單類型,其中一些簡單類型如 string 和decimal是XML Schema中內置的。而其他的一些則是源於(如果使用對象技術的語言,就是繼承)內置的類型。舉例來說,partNum屬性的類型稱爲SKU (Stock Keeping Unit),是源於string.的。內置的簡單類型和他們的後繼版本都能夠被用在所有的元素和屬性聲明中,下面的列表列舉了所有的在XML Schema中內置的簡單類型及其相應的例子。

簡單類型 值示例 備註
string Confirm this is electric  
normalizedString Confirm this is electric 參見 (3)
token Confirm this is electric 參見 (4)
byte -1, 126 參見 (2)
unsignedByte 0, 126 參見 (2)
base64Binary GpM7  
hexBinary 0FB7  
integer -126789, -1, 0, 1, 126789 參見 (2)
positiveInteger 1, 126789 參見 (2)
negativeInteger -126789, -1 參見 (2)
nonNegativeInteger 0, 1, 126789 參見 (2)
nonPositiveInteger -126789, -1, 0 參見 (2)
int -1, 126789675 參見 (2)
unsignedInt 0, 1267896754 參見 (2)
long -1, 12678967543233 參見 (2)
unsignedLong 0, 12678967543233 參見 (2)
short -1, 12678 參見 (2)
unsignedShort 0, 12678 參見 (2)
decimal -1.23, 0, 123.4, 1000.00 參見 (2)
float -INF, -1E4, -0, 0, 12.78E-2, 12, INF, NaN 等同於單精度32位浮點數,其中”NaN”表示”不是一個數字”。參見 (2)
double -INF, -1E4, -0, 0, 12.78E-2, 12, INF, NaN 等同於雙精度64位浮點數。參見 (2)
boolean true, false1, 0  
time 13:20:00.000, 13:20:00.000-05:00 參見 (2)
dateTime 1999-05-31T13:20:00.000-05:00 這個時間表示的含義是:1999年5月31日美東標準時間下午1:20,注意後面的-05:00表示這個時間比格林尼治時間早5個小時。參見 (2)
duration P1Y2M3DT10H30M12.3S 這表示經過了1年2個月3天又10個小時30分鐘12.3秒。
date 1999-05-31 參見 (2)
gMonth --05-- 表示5月。參見 (2) (5)
gYear 1999 表示1999年。參見 (2) (5)
gYearMonth 1999-02 表示1999年2月,而並不關心是幾號。參見 (2) (5)
gDay ---31 表示31號。參見 (2) (5)
gMonthDay --05-31 表示每個5月31號。參見 (2) (5)
Name shipTo XML 1.0的Name類型
QName po:USAddress XML命名空間的QName類型
NCName USAddress XML命名空間的NCName類型,即一個不帶命名空間前綴修飾的QName
anyURI http://www.example.com/, http://www.example.com/doc.html#ID5  
language en-GB, en-US, fr XML 1.0中定義的合法語言代碼
ID   XML 1.0中定義的ID屬性類型。參見 (1)
IDREF   XML 1.0中定義的IDREF屬性類型。參見 (1)
IDREFS   XML 1.0中定義的IDREFS屬性類型。參見 (1)
ENTITY   XML 1.0中定義的ENTITY屬性類型。參見 (1)
ENTITIES   XML 1.0中定義的ENTITYS屬性類型。參見 (1)
NOTATION   XML 1.0中定義的NOTATION屬性類型。參見 (1)
NMTOKEN US, Brésil XML 1.0中定義的NMTOKEN屬性類型。參見 (1)
NMTOKENS US UK, Brésil Canada Mexique XML 1.0中定義的NMTOKENS屬性類型,即一個使用空格作爲元素分隔的NMTOKEN列表。參見 (1)

注意:

  1. 爲了在XML Schema和XML 1.0 DTD之間保持兼容,簡單類型ID、IDREF、IDREFS、ENTITY、ENTITIES、NOTATION、NMTOKEN、NMTOKENS只能用在屬性定義中;
  2. 這個類型的值能夠表示爲不止一種格式,如100和1.0E2都是有效的float格式,它們都表示”一百”這個數值。然而,對於這個類型而言,已經爲其定義了規範的格式規則。
  3. 換行符、製表符和回車符在normalizedString中將會在處理前被轉化成空格字符
  4. 作爲normalizedString,相鄰的空格字符將會被合併爲一個空格字符,第一個和最後的空格將被移走
  5. “g”前綴表示羅馬歷的時間和年代。

新 的簡單類型通過從現有的簡單類型(內置的簡單類型以及源於內置簡單類型的簡單類型)引出定義。特別的,我們通過重新約束一個現存的簡單類型來引出一個新的 簡單類型。換句話說,新類型的合法值範圍是現有類型的值範圍的子集。我們使用simpleType元素來定義和命名新的簡單類型,我們使用 restriction元素來指出現有的基類型。並且用它來標識約束值範圍的細節。

假設我們希望建立一個新的整數類型稱爲myInteger,他的值範圍爲10000到99999。我們的定義應當基於簡單類型integer,然後定義他的值範圍爲10000到99999。爲了定義myInteger,我們這樣來約束integer的範圍(參見下圖):

使用基類型來定義新的簡單類型
<xsd:simpleType name="myInteger">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="10000"/>
<xsd:maxInclusive value="99999"/>
</xsd:restriction>
</xsd:simpleType>

上面的例子顯示了一個由一個基本類型定義和兩個值域區間方面描述的組合,通過這三個要素來對myInteger實施了定義。

而 先前的購買訂單模式文檔則包含了其他的更詳細的定義簡單類型的例子。一個叫SKU的新簡單類型(參見下圖)是從(通過約束)簡單類型string引出的。 此外,我們使用一個稱爲pattern的描述以及pattern的正則表達式值"/d{3}-[A-Z]{2}"來約束SKU的值。其中,該正則表達式值 的語義爲:3個數字後面跟着一個連字號接着跟着兩個大寫的英文字母"。

<xsd:simpleType name="SKU">
<xsd:restriction base="xsd:string">
<xsd:pattern value="/d{3}-[A-Z]{2}"/>
</xsd:restriction>
</xsd:simpleType>

XML Schema定義了15用於簡單類型定義描述的詞彙。在這些詞彙中,enumeration是特別有用的,他能夠被用於約束除boolean類型之外的幾 乎每一個簡單類型。enumeration限制簡單類型的值爲一系列不同的枚舉值。舉例來說,我們可以使用enumeration來定義一個新類型稱爲 USState(參見下圖),USState是從string引出的,同時它的值必須爲美國州的縮寫。

<xsd:simpleType name="USState">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="AK"/>
<xsd:enumeration value="AL"/>
<xsd:enumeration value="AR"/>
<!-- and so on ... -->
</xsd:restriction>
</xsd:simpleType>

USState將會在現在使用的state 元素聲明中成爲string類型的一個非常好的替換品。通過使用這個替換品可以使state元素具有合法值的校驗能力。舉例來說,billTo和 shipTo元素的子元素state,將會被限制在AK,AL,AR等等中。注意到對於特定類型的列舉值必須是唯一的。





回頁首


列表類型(List Type)

除 了在前面描述簡單類型的那個表格中列出的原子類型(這些原子類型可用於組合成絕大多數的其他類型,包括其他的簡單類型和複合類型)外,XML Schema中在簡單類型範疇中還有列表類型的概念。(原子類型、列表類型以及將在下一節中描述的組合類型,總稱爲簡單類型)。一個原子類型的值在XML Schema中是不可分割的。舉例來說,NMTOKEN值US是不可分割的,US的任何部分,如字母S本身都是沒有意義的。與之相比較,列表類型則是由一 組原子類型組成,因此它的每一個部分(原子)本身都是有意義的。舉例來說NMTOKENS是個列表類型。這個類型的元素將是NMTOKEN的列表,不同的 NMTOKEN值間使用空格分隔,如"US UK FR"。XML Schema有三個內置的列表類型,他們是NMTOKENS、IDREFS和ENTITIES。

除了使用內置的 列表類型之外,你還可以通過引用現有的原子類型來建立新的列表類型(你不可以使用現有的列表類型來建立新的列表類型。也不能使用複合類型來建立新的列表類 型)。舉例來說,我們可以建立一個名爲myInteger的列表類型,並在實例文檔中使用它(參見下圖)。其中下圖中的後半部分即爲實例文檔中與列表類型 listOfMyIntType相一致的實例元素。

<!-- Schema Fragment -->
<xsd:simpleType name="listOfMyIntType">
<xsd:list itemType="myInteger"/>
</xsd:simpleType>
<!-- Instance Fragment -->
<listOfMyInt>20003 15037 95977 95945</listOfMyInt>

一些用於描述的參數能夠被應用到列表類型的 定義中,它們是:length、minLength、maxLength和enumeration。舉例來說,如果我們想定義一個列表,這個列表正好包含 了六個美國的州名(SixUSStates)。我們首先從USState定義了一個新的列表類型,稱爲USStateList,然後我們通過限制 USStateList 只有六個項來導出SixUSStates。具體的定義可參見下圖。

<!-- Schema Fragment -->
<xsd:simpleType name="USStateList">
<xsd:list itemType="USState"/>
</xsd:simpleType>
<xsd:simpleType name="SixUSStates">
<xsd:restriction base="USStateList">
<xsd:length value="6"/>
</xsd:restriction>
</xsd:simpleType>
<!-- Instance Fragment -->
<sixStates>PA NY CA NY LA AK</sixStates>

類型爲SixUSStates的元素必須有六個項,他們中的每一個必須是一個枚舉類型USState的原子類型,在上圖後半部分的實例文檔中就是一個具體的應用例子。

此 時,我們需要注意的是,我們可以從原子類型string導出一個列表類型,然而,在一個string中也許會帶有空格,而空格在一個列表類型實例中是作爲 分隔符使用的。所以當在使用基類型爲string的列表類型時,應當格外小心。舉例來說,假設我們定義了一個length取值爲3的列表類型,同時這個列 表類型是基於類型string。以下的由三個元素組成的列表是合法的:"Asie Europe Afrique",而下面的由三個元素組成的列表則是不合法的:"Asie Europe Amérique Latine"。

即使"Amérique Latine"在列表外可以作爲單獨的一個字符串存在,但當它包含在列表中,在Amérique和Latine之間的空格使得第四個項被有效地生成了,因此後面的那個例子不符合只有三個項的列表類型定義。





回頁首


聯合類型(Union Type)

應 用原子類型和列表類型,一個元素或者屬性的值可以爲一個或者多個原子類型(列表類型)的實例。與之相比較,如果應用聯合類型,一個聯合類型包含了多個原子 類型或者列表類型,而應用了聯合類型的元素或是屬性的值可以是這些原子類型或列表類型中的一個類型的實例。爲了顯示這點,我們建立一個用於表示美國的州 的,爲兩個字母縮寫或者數字列表的聯合類型。zipUnion聯合類型由一個原子類型和一個列表類型構成的(參見下圖)。

<!-- Schema Fragment -->
<xsd:simpleType name="zipUnion">
<xsd:union memberTypes="USState listOfMyIntType"/>
</xsd:simpleType>
<!-- Instance Fragment -->
<zips>CA</zips>
<zips>95630 95977 95945</zips>
<zips>AK</zips>

當我們在定義一個聯合類型時,元素union的memberTypes屬性的值包含了聯合類型中所有類型的列表。現在,假定我們聲明瞭一個zipUnion類型的元素,稱爲zips,zips元素有效的實例可參見上圖。

此外,對於聯合類型而言,還有兩個描述性質的參數pattern和enumeration也可以應需要使用。

Copyrightc 2001 W3C,( MIT, INRIA, Keio),All Rights Reserved.



參考資料

 
發佈了25 篇原創文章 · 獲贊 1 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章