現在的語言,如果不有那么一點OO的影子,都不好意思稱之為語言了。在XML的語義約束方面,DTD雖然簡單,但是功能不夠強大,完全是直白的描述,於是又有了替代DTD的XSD(XML Schema Definition),XSD引入了數據類型,提供了自定義數據類型的各種機制,甚至還能找到繼承、多態等各種OO特征,然而學習起來也就相對復雜了,從這篇筆記開始學習一下XSD。
1、XSD文件是一種XML文件
XSD文件是一種XML文件,滿足所有XML文件格式的一切要求,比如有且僅有一個根元素(這個根元素就是<schema/>),所有對XML文件有效的技術對XSD文件也同樣有效,包括使用XSD文件作為語義約束。
2、XSD文件的根元素
XSD文件的根元素是<schema/>,它還可以有自己的屬性,我們先看看spring-beans-3.2.xsd這個例子:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!--xsd文件本身是xml文件,第一行是xml聲明--> <xsd:schema xmlns="http://www.springframework.org/schema/beans" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.springframework.org/schema/beans"> <!-- xsd作為xml文件,其根元素是schema 屬性xmlns:xsd="http://www.w3.org/2001/XMLSchema"是引入文檔約束的,表示在當前文檔導入"http://www.w3.org/2001/XMLSchema"中所描述的規則,並且使用里面的元素要添加xsd的前綴(和xmlns:xsd相對應,也可以指定其它前綴) 屬性targetNamespace="http://www.springframework.org/schema/beans"表示當前文檔定義的規則處於命名空間"http://www.springfarmework.org/schema/beans"下面,xml文檔如需要導入當前文檔的規則,就可以指定這個命名空間 屬性xmlns="http://www.springframework.org/schema/beans"表示在當前文檔中導入"http://www.springframework.org/schema/beans"命名空間下所描述的規則(即當前文檔本身描述的規則),並且無需使用前綴,也即默認命名空間,這樣,在當前文檔就可以直接引用所定義的元素了
--> </xsd:schema>
我不知道第一次看見這個解釋的人有沒有迷糊,反正我第一次從w3c的教材上看到的時候是迷糊了,不過沒關系,我們的目的主要是應用,以后寫xsd文件的時候仿照spring就可以了。
根元素schema的屬性列表如下(先混個眼熟):
| 屬性 | 說明 | 取值 |
| id | 標識該元素的唯一ID | |
| attributeFormDefault | 指定XML文檔使用schema中定義的局部屬性時是否必須使用命名空間限定 | qualified:必須通過命名空間前綴限定 unqualified:(默認值)無須通過命名空間前綴限定 |
| elementFormDefault | 指定XML文檔使用schema中定義的局部元素時是否必須使用命名空間限定 | 取值和含義同attributeFormDefault |
| blockDefault | 設定schema中element和complexType上的block屬性的默認值 block屬性用來阻止以指定的派生類型代替原類型 |
#all或者extension、restriction和substitution的自由組合 例如extension表示防止通過擴展派生的復雜類型替代該復雜類型 |
| finalDefault | 設定schema中element、simpleType和complexType上的final的默認值 final屬性用來阻止以指定的派生類型來派生新類型 |
對於element和complexType:值可以是#all或extension和restriction的自由組合 對於simpleType:值可以是#all或restriction、list和union的自由組合 |
| targetNamespace | 設定schema的命名空間的URI引用 | |
| version | 設定schema的版本 | |
| xmlns | 設定schema使用的一個或多個命名空間的URI引用 | |
| any attributes | 設定帶有non-schema命名空間的任何其他屬性 |
3、在xml文檔中使用xsd文件
根據被引用的xsd文件是否定義了targetNamespace屬性,可以分兩種情況導入相應的xsd文件:
(1)引入無命名空間的XSD
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="無命名空間XSD文件的URI"> <!-- 1.第一步,添加xmlns:xsi屬性,引入xsi命名空間 2.第二步,通過xsi命名空間下的屬性noNamespaceSchemaLocation指定XSD文件的URI --> </root>
(2)引入有命名空間的XSD
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns1="前綴ns1對應命名空間" xmlns:ns2="前綴ns2對應命名空間" xsi:schemaLocation="ns1前綴對應命名空間 前綴ns1對應命名空間XSD文件的URI ns2前綴對應命名空間 前綴ns2對應命名空間XSD文件的URI"> <!-- 1.第一步,添加xmlns:xsi屬性,引入xsi命名空間 2.第二步,添加命名空間,可添加多個,但沒有前綴的命名空間最多只能有1個 3.第三步,通過xsi命名空間下的屬性schemaLocation指定每個命名空間XSD文件的URI,命名空間和相應URI一一對應,多個命名空間用空格分隔 --> </root>
這里提醒一下:XSD文件引入的是w3的XMLSchema,而一般的XML文檔引入的是XMLSchema-instance。
4、XSD文件的注釋
作為XML文件,XSD文件自然也可以使用<!-- -->的注釋格式,除此之外,XSD文件中還可以使用XML元素的方式來注釋,這就是<annotation>元素,<annotation>元素則是通過使用<document>和<appinfo>兩個子元素來起作用的,其中<document>主要放適合人類閱讀的注釋,而<appinfo>則主要放置針對其它應用程序的注釋信息。Spring的XSD文件中有大量的使用
<annotation> <document><![CDATA[ 說明文字 ]]></document> </annotation>
格式的注釋,這里就不舉例了。
5、在XSD文件中導入其它的XSD文件
在XSD文件中,如果你覺得有必要,還可以導入其它的XSD文件,這有點OO中模塊化的意思,將相關的定義封裝在一個XSD文件里,然后通過導入在其它XSD文件中使用。導入的方式有三種,列個表比較一下:
| 導入方式 | 前提條件 | 屬性 |
| include | 被導入XSD文件要么沒有命名空間,要么命名空間和當前文件相同,導入后相當於在同一個文件中定義 | id:指定<include>元素本身的唯一標識;schemaLocation:指定被導入XSD文件的URI |
| redefine | 前提和include相同,不同的是redefine可以接受<simpleType>或<complexType>從而重定義被導入XSD中內容 | 同include元素的屬性相同 |
| import | 被導入XSD文件要么沒有命名空間,要么命名空間和當前文件不同,因此import導入的XSD文件會保留原來的命名空間 | 除id和schemaLocation外,還有一個namespace屬性用於指定被導入XSD文件的命名空間 |
說明一下,類似於C語言中的#include,導入XSD文件的元素只能作為根元素<schema>的子元素,並且位於除了注釋元素<annotation>外所有元素的前面,至於三種導入方式的順序則沒有要求。
6、XSD元素
在XSD中,最強大的在於提供了數據類型的支持,並且可以自定義數據類型,在這篇筆記中我並不想就此進入XSD數據類型的泥潭,依舊先在外面轉悠轉悠,對XSD文件中的元素混個眼熟,這些元素相當於編程語言中的關鍵字,XSD就是用這些元素定義XML結構的,也可以直接訪問W3C在線教程的相關部分:XML Schema參考手冊
| 元素 | 解釋 |
|---|---|
| all | 規定子元素能夠以任意順序出現,每個子元素可出現零次或一次。 |
| annotation | annotation 元素是一個頂層元素,規定 schema 的注釋。 |
| any | 使創作者可以通過未被 schema 規定的元素來擴展 XML 文檔。 |
| anyAttribute | 使創作者可以通過未被 schema 規定的屬性來擴展 XML 文檔。 |
| appInfo | 規定 annotation 元素中應用程序要使用的信息。 |
| attribute | 定義一個屬性。 |
| attributeGroup | 定義在復雜類型定義中使用的屬性組。 |
| choice | 僅允許在 <choice> 聲明中包含一個元素出現在包含元素中。 |
| complexContent | 定義對復雜類型(包含混合內容或僅包含元素)的擴展或限制。 |
| complexType | 定義復雜類型。 |
| documentation | 定義 schema 中的文本注釋。 |
| element | 定義元素。 |
| extension | 擴展已有的 simpleType 或 complexType 元素。 |
| field | 規定 XPath 表達式,該表達式規定用於定義標識約束的值。 |
| group | 定義在復雜類型定義中使用的元素組。 |
| import | 向一個文檔添加帶有不同目標命名空間的多個 schema。 |
| include | 向一個文檔添加帶有相同目標命名空間的多個 schema。 |
| key | 指定屬性或元素值(或一組值)必須是指定范圍內的鍵。 |
| keyref | 規定屬性或元素值(或一組值)對應指定的 key 或 unique 元素的值。 |
| list | 把簡單類型定義為指定數據類型的值的一個列表。 |
| notation | 描述 XML 文檔中非 XML 數據的格式。 |
| redefine | 重新定義從外部架構文件中獲取的簡單和復雜類型、組和屬性組。 |
| restriction | 定義對 simpleType、simpleContent 或 complexContent 的約束。 |
| schema | 定義 schema 的根元素。 |
| selector | 指定 XPath 表達式,該表達式為標識約束選擇一組元素。 |
| sequence | 要求子元素必須按順序出現。每個子元素可出現 0 到任意次數。 |
| simpleContent | 包含對 complexType 元素的擴展或限制且不包含任何元素。 |
| simpleType | 定義一個簡單類型,規定約束以及關於屬性或僅含文本的元素的值的信息。 |
| union | 定義多個 simpleType 定義的集合。 |
| unique | 指定屬性或元素值(或者屬性或元素值的組合)在指定范圍內必須是唯一的。 |
