XSD提供了數據類型,而且支持自定義數據類型,但這一切都是創建在XSD內置數據類型和一套擴展內置數據類型的規則基礎之上的,在這一篇筆記中,就來看看XSD中的數據類型。git
一、XSD數據類型圖正則表達式
先看一下數據類型圖,有個大概的輪廓,後面再進一步細化:ui
從上面的XSD數據類型圖能夠看出,主要分紅兩個大類:編碼
(1)簡單類型:能夠給屬性使用,也能夠給元素使用,除了內建類型,也可使用<simpleType>自定義簡單類型,而自定義的方式有三種:限制<restriction>、列表<list>、聯合<union>。spa
(2)複雜類型:只能給元素使用,而且所有須要使用<complexType>來自定義,根據內容又可進一步區分爲含簡單內容的複雜類型和含複雜內容的複雜類型,分別使用<simpleContent>和<complexContent>定義其內容。另外,複雜類型還可使用限制<restriction>和擴展<extension>來派生新的類型。rest
複雜類型只能給元素使用,這大概也是爲何要區分簡單類型和複雜類型的緣由。code
二、內建類型orm
內建類型具備基本的重要地位,是派生其它類型的基礎,首先仍是從官方文檔中截一副內建類型的繼承關係圖下來:xml
圖例中的幾個說明:built-in primitive types(內建基本類型)、built-in derived types(內建派生類型)、complex types(複雜類型)、derived by restriction(經過限制派生)、derived by list(經過列表派生)、derived by extension or restriction(經過限制或擴展派生)。blog
第一印象看這幅圖,彷佛是兩根柱子(string及其派生、decimal及其派生)上面架設了兩層商鋪,柱子是脊樑,商鋪是裝飾——扯遠了點,仍是具體的看看這些內建類型吧!
(1)字符串類型
注意QNAME雖然是字符串類型數據,但由於派生機制的問題,並非派生自string。
類型 | 說明 | ||||||
QNAME | 帶命名空間前綴的XML標籤名,容許省略命名空間,但省略時不能以冒號開頭,而且使用命名空間時不能以冒號結尾 | ||||||
string | 字符串,可包括字符、換行、回車以及製表符等,會原封不動保留全部字符 | ||||||
normalizedString | 會將字符串中的換行、回車以及製表符都替換成空格 | ||||||
token | 將換行、回車及製表符替換成空格,並自動刪除先後空格,將中間的多個連續空格壓縮成一個空格 | ||||||
language | 合法的語言代碼,如en-GB、en-US、fr、zh-CN等 | ||||||
Name | 合法的XML標籤名,即由字母、數字、下劃線、中劃線、冒號、點號組成,且不能以數字、中劃線、點號開頭 | ||||||
NCName | 不帶命名空間的合法的XML標籤名,即不能含冒號 | ||||||
ID | 同DTD,在XML文檔中必須惟一,只能用於屬性,不能用於元素。 | ||||||
IDREF | 同DTD,必須是引用已有的ID屬性值,只能用於屬性,不能用於元素 | ||||||
IDREFS | 同DTD,必須是引用已有的一個或多個ID屬性值,多個使用空格分隔,只能用於屬性,不能用於元素 | ||||||
ENTITY | 同DTD,外部實體,只能用於屬性,不能用於元素 | ||||||
ENTITIES | 同DTD,一個或多個外部實體,多個使用空格分隔,只能用於屬性,不能用於元素 | ||||||
NMTOKEN | 同DTD,合法的XML標籤名,且只能由字母、數字、下劃線、中劃線、點號、冒號組成 | ||||||
NMTOKENS | 同DTD,一個或多個NMTOKEN,多個使用空格分隔,只能用於屬性,不能用於元素 |
(2)數值類型
float和double類型還能夠接受的特殊值:-INF(負無窮大)、INF(正無窮大),NaN(非數)、+0(正零)和-0(負零)。其中正零大於負零,NaN大於全部數值(包括INF),INF大於全部浮點數。
類型 | 說明 | ||||||
float | 32位的單精度浮點數,可以使用科學計數法,整數部分爲0時可省略,但不能省略小數點,不能用f/F後綴 | ||||||
double | 64位的雙精度浮點數,可以使用科學計數法,整數部分爲0時可省略,但不能省略小數點 | ||||||
decimal | 精確小數,不能使用科學計數法,不能接受-INF、INF、NaN等特殊值 | ||||||
integer | 表明任意大的整數 | ||||||
nonPositiveInteger | 非正整數 | ||||||
negativeInteger | 負整數 | ||||||
long | 64位的有符號整數 | ||||||
int | 32位的有符號整數 | ||||||
short | 16位的有符號整數 | ||||||
byte | 8位的有符號整數 | ||||||
nonNegativeInteger | 非負整數 | ||||||
positvieInteger | 正整數 | ||||||
unsignedLong | 64位的無符號整數 | ||||||
unsignedInt | 32位的無符號整數 | ||||||
unsignedShort | 16位的無符號整數 | ||||||
unsignedByte | 8位的無符號整數 |
(3)布爾類型
布爾類型能夠接受true、false、1(表示true)、0(表示false)四個值。
(4)日期和時間類型
類型 | 格式 | 說明 |
date | YYYY-MM-DD | 日期 |
time | hh:mm:ss.sss | 時間,sss表示毫秒數 |
dateTime | YYYY-MM-DDThh:mm:ss.sss | 日期時間,中間的T是必須的,是日期和時間的分隔符 |
gYear | YYYY | 年 |
gYearMonth | YYYY-MM | 年月 |
gMonth | --MM | 月,前面的兩個中劃線是必須的 |
gMonthDay | --MM-DD | 月日,前面的兩個中劃線是必須的 |
gDay | ---DDD | 日,前面的三個中劃線是必須的 |
duration | PnYnMnDTnHnMnS | 定義時間間隔,P是固定的,表示週期,S前的n能夠有小數部分,其它必須是整數 |
說明:上面列出的前8個類型後面能夠添加Z表示UTC時間;Y、M、D、h、m、s分別表示年月日時分秒,均可替換爲一個有效的整數,其中,年份不夠4位左邊補0,前面加負號表示公元前,月日時分秒不夠2位左邊補0,毫秒sss能夠是1-3位的整數。
(5)二進制數據類型
XSD中有下面兩種二進制數據類型:
A:hexBinary,以十六進制保存的二進制數據,所以只能由0~九、a~f、A~F等字符組成,字符長度必須是偶數。
B:base64Binary,以Base64編碼保存的任意二進制數據,所以只能由0~九、a~f、A~F和加號+等字符組成,字符長度必須是4的倍數。
(6)anyURI類型:合法的URI。
(7)NOTATION類型:同DTD,表示合法的符號。
三、自定義簡單數據類型
(1)使用<simpleType>元素自定義簡單數據類型的語法以下:
<simpleType id=ID name=NCName final=... any-attributes> (annotation?,(restriction|list|union)) <!-- 1.id屬性是可選的,用於惟一標識<simpleType>元素自己 2.name屬性表示自定義數據類型的名稱,值是NCName類型,而且必須在全部<simpleType>和<complexType>之間惟一,<simpleType>是<schema>的子元素時必須指定,這個時候新定義的數據類型爲全局的數據類型 --> </simpleType>
(2)能夠在schema元素下定義全局數據類型,也能夠在其它元素下定義局部數據類型。
(3)屬性final用來限制派生新的類型,默認值爲根元素<schema>的finalDefault屬性的值,能夠取的值有:
A、#all:限制該類型以任何形式派生新的類型
B、restriction、list、union的自由組合:限制使用指定的方式派生新的類型
C、"":不作任何限制
四、經過限制派生自定義數據類型
從語法上看,使用<simpleType>元素自定義簡單類型,具體有三種方式:限制<restriction>、列表<list>、聯合<union>。這一小節先看第一種:限制<restriction>。
(1)語法格式以下:
<simpleType ...> <restriction id=ID base=QNAME any-attributes> <!--1.處於<simpleType>元素下的語法--> (annotation?,(simpleType?,(12種數據類型約束)*)) </restriction> </simpleType> <simpleContent ...> <restriction id=ID base=QNAME any-attributes> <!--2.處於<simpleContent>元素下的語法--> (annotation?,(simpleType?,(12種數據類型約束)*)?,((attribute|attributeGroup)*,anyAttribute?)) </restriction> </simpleContent> <complextContent ...> <restriction id=ID base=QNAME any-attributes> <!--3.處於<complextContent>元素下的語法--> (annotation?,(group|all|choice|sequence)?,((attribute|attributeGroup)*,anyAttribute?)) </restriction> </complextContent>
其中id屬性惟一標識<restriction>元素自己,可選的;base屬性表示在該schema(或由指定命名空間指示的其它schema)中定義的內建數據類型、simpleType或complexType元素的名稱,也能夠不指定base屬性,而直接使用<simpleType>子元素來定義被限制的基類型。
(2)約束:在XSD中,限制是經過在基類型上添加約束來實現的,那麼,又有哪些約束呢?這些約束又能夠應用到哪些基類型呢?
分類 | 可做用的數據類型 | 約束 | 描述 |
枚舉約束 | enumeration | 可接受值的列表 | |
精度約束 | decimal | fractionDigits | 容許的最多的小數位數 |
totalDigits | 容許的數字的最多位數(不包括小數點) | ||
長度約束 | string、QName、anyURI、二進制數據 還可用於約束列表類型列表項的數目 |
length | 字符長度或者列表項目的數目 |
maxLength | 字符長度或者列表項目的數目的最大值 | ||
minLength | 字符長度或者列表項目的數目的最小值 | ||
範圍約束 | 能夠比較大小的類型,如數值、日期等 | maxExclusive | 容許數值的上限,不能等於上限值 |
minExclusive | 容許數值的下限,不能等於下限值 | ||
maxInclusive | 容許數值的上限,可等於上限值 | ||
minInclusive | 容許數值的下限,可等於下限值 | ||
正則表達式約束 | 各類數據類型 | pattern | 使用正則表達式約束能夠出現的字符 |
空白處理約束 | whiteSpace | 定義空白字符(換行、回車、空格、製表等)的處理方式 preserve:原樣保留全部空白 replace:替換全部空白字符爲空格 collapse:先replace,再去掉首尾空格,並將中間連續空格壓縮爲一個 |
在派生新的類型時,若是原來類型有一個約束,新派生類型使用相同的約束,且新約束範圍在原約束範圍以內,則新類型的約束將會覆蓋原類型的約束。但有時候,想阻止派生類型覆蓋已有的約束,這個時候能夠在原類型的約束上添加fixed屬性(true|false)。
<list id=ID itemType=QName any-attributes> (annotatin?,(simpleType?)) </list>
(2)指定列表成員類型的方法
A、使用itemType屬性
B、使用子元素<simpleType>,這個時候不能指定itemType屬性
(3)實際上,內置的IDREFS、ENTITIES、NMTOKENS分別是IDREF、ENTITY、NMTOKEN類型的列表類型。
(4)使用空格做爲列表類型值的分隔符。
(5)能夠對列表類型使用長度約束(約束列表項的個數)、枚舉約束、正則表達式約束和空白處理約束(但值只能是collapse),須要注意的是,枚舉約束和正則表達式約束的是整個列表類型的值,而不只僅只是其中一個列表項值。
六、經過聯合派生自定義數據類型
(1)聯合<union>元素的語法:
<union id=ID memberTypes="QName列表" any-attributes> (annotatin?,(simpleType*)) </union>
(2)指定聯合成員類型的方法
A、使用屬性memberTypes,多個類型使用空格分隔
B、使用一個或多個子元素<simpleType>
(3)能夠對聯合類型使用枚舉約束和正則表達式約束,一樣,約束的也是整個聯合類型的值。
(4)列表類型和聯合類型都是在現有類型的基礎上派生新類型,在XSD中還可使用<list>元素由聯合類型派生出相應的列表類型,也可使用<union>元素將一個或多個已有的列表類型派生出新的聯合類型,不過須要注意的是,不能使用列表類型派生新的列表類型,也不能使用含有列表類型的聯合類型派生新的列表類型。
七、最後看一個使用三種方式自定義簡單類型的實例:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <!--從int派生的ageType--> <xs:simpleType name="ageType"> <xs:restriction base="xs:int"> <xs:maxInclusive value="100"/> <xs:minInclusive value="0"/> </xs:restriction> </xs:simpleType> <!--由ageType派生出對應的列表類型--> <xs:simpleType name="ageListType"> <xs:list itemType="ageType"/> </xs:simpleType> <!--從string派生的nameType--> <xs:simpleType name="nameType"> <xs:restriction base="xs:string"> <xs:maxLength value="20"/> <xs:minLength value="4"/> </xs:restriction> </xs:simpleType> <!--由nameType派生出對應的列表類型--> <xs:simpleType name="nameListType"> <xs:list itemType="nameType"/> </xs:simpleType> <!--由ageType和nameType派生出聯合類型--> <xs:simpleType name="ageType_nameType"> <xs:union memberTypes="ageType nameType"/> </xs:simpleType> <!--使用兩個列表類型派生聯合類型--> <xs:simpleType name="ageListType_nameListType"> <xs:union memberTypes="ageListType nameListType"/> </xs:simpleType> <!--使用兩個聯合類型派生聯合類型--> <xs:simpleType name="furtherType"> <xs:union memberTypes="ageType_nameType ageListType_nameListType"/> </xs:simpleType> <!--一個列表類型,一個聯合類型派生聯合類型--> <xs:simpleType name="furtherMixType"> <xs:union memberTypes="nameListType ageListType_nameListType"/> </xs:simpleType> <!--由聯合類型派生出對應的列表類型--> <xs:simpleType name="ageType_nameType_ListType"> <xs:list itemType="ageType_nameType"/> </xs:simpleType> </xs:schema>