Schema簡介
XML Schema也被稱為XML Schema定義(XML Schema Definition,XSD)。和DTD一樣,Schema也是XML的約束,同樣用于定義合法的XML文檔構建模塊。與DTD不同的是,XML Schema是用一套預先定義好的XML元素和屬性創建的,這些元素和屬性規定了XML文檔的結構和內容模式,且XML Schema規定XML文檔實例的結構和每一個元素或屬性的數據類型。另外,Schema相對于DTD有一個明顯的好處就是,Schema是基于XML編寫的,自己本身也是一個XML文檔(文件后綴名為.xsd
),而不是像DTD有自成一套的語法,這也是Schema能比DTD更被廣泛應用的原因。
再次以之前介紹DTD約束用到的XML文檔為例:
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id=“01”>
<name>三體</name>
<author>劉慈欣</author>
<price>23.8</price>
</book>
<book id=“02”>
<name>龍族</name>
<author>江南</author>
<price>19.6</price>
</book>
</books>
名稱空間
在編寫了一個XML Schema約束文檔后,通常需要把這個文檔定義的元素和屬性綁定到一個URI地址上,這個地址就叫做名稱空間。接著XML文檔通過這個名稱空間告訴解析引擎,文檔中的元素和屬性來自哪里。名稱空間有什么用呢?就是用來唯一標識元素和屬性來自哪個Schema。簡單來說,當一個XML實例文檔引用了多個Schema的時候,倘若這些Schema定義了同名的元素或屬性,名稱空間就可以將它們區分開來。
預定義元素和屬性
上面說過,XML Schema是用一套預先定義好的XML元素和屬性創建的,而這套元素和屬性是由W3C定義的,然后綁定在一個URI上,在編寫Schema文檔時直接引用這個名稱空間即可。
編寫Schema文檔
W3C規定,Schema文檔的根元素必須為schema
。首先要引用W3C預定義好的元素和屬性,語法為:
xmlns="http://www.w3.org/2001/XMLSchema"
這里的名稱空間一般來說是固定的,大家記住就行。xmlns
是根元素schema
的一個屬性。
接著定義元素和屬性,與之前介紹過的DTD一樣,XML文檔中的每一個元素都要對應一個element
,語法為:
<element name="元素名稱"></element>
例如,對于上文的XML文檔,Schema的元素定義應為
<element name="books"></element>
<element name="book"></element>
<element name="name"></element>
<element name="author"></element>
<element name="price"></element>
對于出現多次的元素,定義中可以為element
添加minOccurs
屬性和maxOccurs
屬性來表示元素出現的最少次數和最多次數,而不確定(次數)可用unbounded
來表示。所以,語法為:
-
元素出現零次或一次:
<element name="元素名稱" minOccurs="0" maxOccurs="1"></element>
-
元素出現零次或多次:
<element name="元素名稱" minOccurs="0" maxOccurs="unbounded"></element>
-
元素出現一次或多次:
<element name="元素名稱" minOccurs="1" maxOccurs="unbounded"></element>
這里介紹復雜元素的概念,一個元素如果包含子元素和屬性,就是簡單元素,反之就是復雜元素。
對于簡單元素,定義中可以為element
元素添加type
屬性來表示元素的數據類型(復雜元素則不能這樣做):
<element name="元素名稱" type="數據類型"></element>
對于含有多個子元素的元素(復雜元素),定義語法應為:
<element name="元素名稱">
<complexType>
<sequence>
<element name="子元素名稱1" ...></element>
<element name="子元素名稱2" ...></element>
<element name="子元素名稱3" ...></element>
</sequence>
</complexType>
</element>
這里的sequence
元素規定了子元素出現的順序,需要注意的是,即使是只有一個子元素的元素,定義語法也為:
<element name="元素名稱">
<complexType>
<sequence>
<element name="子元素名稱" ...></element>
</sequence>
</complexType>
</element>
sequence
元素不可缺少。
說完了對元素的定義,接下來介紹對屬性的定義。定義屬性的語法為:
<attribute name="屬性名稱" type="數據類型" 屬性類型></attribute>
下面是Schema中的數據類型:
這里的屬性類型若不注明,則認為屬性是可選的(即不強制要求存在)。除此之外,屬性類型一般分為三種:
-
必選:語法為:
<attribute name="屬性名稱" type="數據類型" use="required"></attribute>
-
有默認值:語法為:
<attribute name="屬性名稱" type="數據類型" default="默認值"></attribute>
-
有固定值:語法為:
<attribute name="屬性名稱" type="數據類型" fixed="固定值"></attribute>
對于包含屬性的元素,前面說過屬于復雜元素(即使這個元素只含屬性不含子元素),因此定義應為:
<element ...>
<complexType>
<attribute ...></attribute>
</complexType>
</element>
對元素和屬性定義完了,最后要做的就是要讓XML實例文檔引用這個Schema,也就是引用定義好的元素和屬性,因此就要為這些元素和屬性指定一個名稱空間。語法為:
targetNamespace="名稱空間"
這個名稱空間是自己定義的URI地址,我采用的是Eclipse的默認設置,為http://www.example.org/Schema文件名
。
同樣,targetNamespace
也是根元素schema
的一個屬性。因此,對于上文的XML文檔,Schema文檔應為:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/books">
<element name="books">
<complexType>
<sequence>
<element name="book" minOccurs="1" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="name" type="string"></element>
<element name="author" type="string"></element>
<element name="price" type="double"></element>
</sequence>
<attribute name="id" type="string" use="required"></attribute>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
以上就是對Schema文檔的編寫。
修改XML實例文檔
既然已經有了Schema文檔作為約束,在XML實例文檔中就要去引用它。和編寫Schema文檔的第一步一樣,首先要引用定義好的元素和屬性,語法也為:
xmlns="名稱空間"
這里的名稱空間則不是W3C那個了,而是作為約束的Schema文檔為定義好的元素和屬性所綁定的名稱空間,對于我來說就是http://www.example.org/books
。
接下來是聲明這個XML文檔是應用了Schema約束技術的一個實例,語法為:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
這個語法是固定的,大家記住就行。
最后就是指定Schema文檔的位置進行引用,語法為:
xsi:schemaLocation="名稱空間 Schema文件名"
這里的名稱空間也是Schema文檔所綁定的名稱空間。
xmlns
、xmlns:xsi
和xsi:schemaLocation
都是XML實例文檔根元素的屬性,因此,對文檔的修改實際上只是添加這三個屬性,其他內容不用修改。上文的XML文檔應修改為:
<?xml version="1.0" encoding="UTF-8"?>
<books xmlns="http://www.example.org/books"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/books books.xsd">
<book id=“01”>
<name>三體</name>
<author>劉慈欣</author>
<price>23.8</price>
</book>
<book id=“02”>
<name>龍族</name>
<author>江南</author>
<price>19.6</price>
</book>
</books>
參考資料
Schema相對于DTD來說語法更復雜,語法細節也更多,這里只是簡單介紹了一些基本知識,而更復雜的語法也代表著更詳盡的功能,這也是Schema能逐步取代DTD的原因了。