1. 程式人生 > >XML文件型別定義---XML Schema

XML文件型別定義---XML Schema

XML Schema是2001年5月正式釋出的W3C的推薦標準,經過數年的大規模討論和開發如今終於塵埃落定,成為全球公認的XML環境下首選的資料建模工具。 
使用DTD雖然帶來較大的方便,但是,DTD存在一些缺陷:一是它用不同於XML的語言編寫,需要不同的分析器技術。這增加了工具開發商的負擔,降低了軟體瘦身的可能性,此外開發人員需要多學一門語言及其語法。而XML Schema是按標準XML規則編寫的,更容易掌握。二是DTD不支援名稱空間。隨著大部分的資料處理日益以XML為中心,資訊的相互聯絡變得日益普及與深入,名稱空間作用也將凸現。三是DTD在支援繼承和子類方面的侷限性。由於面向物件技術的出現,對繼承和子類的支援已成為軟體技術領域的主流概念。最後,DTD沒有資料型別的概念,無法對特定元素施加資料型別,對強制性結構化無計可施,例如,如何規定名為Date的資料必須包含有效值。 
這些就要依靠XML Schema了。XML Schema不僅可以定義XML文件的結構而且還允許約束文件的內容,這不同於DTD。另外,一個 XML Schema自身就是一個XML文件,其基於標籤的語法比DTD中的特殊字元要清楚多了。XML Schema正是針對這些DTD的缺點而設計的,它完全使用XML作為描述手段,具有很強的描述能力、擴充套件能力和處理維護能力。 
XML Schema是用一套預先規定的XML元素和屬性建立的,這些元素和屬性定義了文件的結構和內容模式。 
XML Schema也是Web Services技術中需要使用的一個基本工具,然而並不是XML Schema的所有特性都會被廣泛地使用,因此,本書將不對XML Schema規範做系統的介紹。目前主要有兩種重要的模式:Microsoft XML Schema和W3C XML Schema,本章主要討論W3C XML Schema

。 
在下面的例子中,通過使用出現在Schema元素中的名稱空間宣告xmlns:xsd= “http://www.w3.org/2001/XMLSchema”,使得模式文件中的每一個元素都有一個與XML Schema名稱空間相關聯的名稱空間字首xsd。儘管在語法上,可以使用任意的字首形式,但是,名稱空間字首xsd被約定用於表示XML Schema名稱空間。由於使用同樣的字首,所以同樣的關聯就會出現在內建的簡單型別的名字中,例如xsd:string。這種形式關聯的目的是用來表示當前的元素或簡單型別屬於XML Schema語言的內建定義,而不屬於模式文件作者自己的詞彙表。為了在這裡清楚並且簡單地表示,僅提及元素的名字和簡單型別名,而忽略它們的字首xsd。

5.2 Schema的格式和使用

一個XSDL(XML Schema Definition Language)文件由元素、屬性、名稱空間和XML文件中的其他結點構成,並且至少要包含:schema根元素XML模式名稱空間的定義元素定義

5.2.1 簡單例項

【例5.1】 關於書籍資訊的XML文件,程式碼如源程式code5_1.xml所示。

<?xml version="1.0" encoding="gb2312"?>
<book isbn="0-764-58007-8">
    <title>三國演義</title>
    <author
>
羅貫中</author> <price>80.00 </price> <resume>滾滾長江東逝水,浪花淘盡英雄。是非成敗轉頭空。青山依舊在,幾度夕陽紅。白髮漁樵江渚上,慣看秋月春風。一壺濁酒喜相逢。古今多少事,都付笑談中。 </resume> <recommendation>經典好書</recommendation> <publish> <publisher>文藝出版社</publisher> <pubdate>1998.10</pubdate> </publish> </book>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

如何寫這個XML文件的Schema呢?可以簡單地依照它的結構來定義它的每個元素。首先加入一個xsd:schema元素。

<?xml version="1.0" encoding=" gb2312"?> 
<xsd:schema xmlns:xsd="http://www.w3.org/2000/10/XMLSchema">
  • 1
  • 2
  • 1
  • 2

每個Schema文件都是從schema元素開始,並且只能有一個,用以控制Schema所使用的名稱空間和另外幾個選項,現在的Schema標準有好幾種,這裡決定它所採用的標準,因此是非常重要的。 
對應著XML文件的book元素,同樣也定義一個名為book的元素(element)。因為這個元素有屬性(attributes)和非文字的子元素(non-text children),所以認為它是一個複雜型別(complexType)。而對於簡單型別,只能有值,不能有子元素或者屬性。同時還注意到book元素下的子元素,都按照一定的順序排列,因此使用順序元素(sequence element)來描述。

<xsd:element name="book">
<xsd:complexType>
<xsd:sequence>
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

順序元素(sequence element)是一個定義子元素排列順序的元素,在下面的章節,還將介紹其他類似的元素,如選擇(choice)和全選(all)。 
接著定義title和author,都是xsd:string型別的簡單元素,因為沒有屬性(attributes)或者子元素。xsd:string是一個已經在名域中預定義了的XML Schema型別中的一個。

<xsd:element name="title" type="xsd:string"/>
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="price" type="xsd:integer" />
<xsd:element name="resume" type="xsd:string" />
<xsd:element name="recommendation" type="xs:string" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

接著,來處理publish元素,它也是一個複雜型別,注意它的基數的定義。

<xsd:element name="publish" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

同其他Schema定義語言不一樣,W3C XML Schema允許定義一個元素的使用基數,能指定元素的minOccurs(最小數)maxOccurs(最大數)。這裡設定maxOccurs為unbounded,這意味著能有任意多的publish元素。這兩個屬性的預設值都是1。下面,用同樣的方法定義其他的子元素。

<xsd:element name="publisher" type="xsd:string" />
<xsd:element name="pubdate" type="xsd:date" />
  • 1
  • 2
  • 1
  • 2

下面封閉complexType和element等元素。

</xsd:sequence>
</xsd:complexType>
</xsd:element>
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

這樣publish元素就完成了,然後封閉book的sequence元素。

</xsd:sequence>
  • 1
  • 1

現在,宣告book元素的屬性,通常是在最後這麼做。這樣做沒有什麼特別的原因,只不過W3C XML Schema工作組認為在元素後定義屬性感覺更加自然。

<xsd:attribute name="isbn" type="xsd:string"/>
  • 1
  • 1

最後,封閉所有剩下的元素。

</xsd:complexType>
</xsd:element>
</xsd:schema>
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

至此,一個Schema已經完成了。其中,最關鍵的在於根據文件的上下關係來定義每一個元素和屬性,並且允許有多個同名元素帶有不同的內容。為了這個目的,W3C XML Schema被設計成一種有作用域的語言,它的每一個定義只能被它定義的子元素所看見。 
【例5.2】 關於books.xml模式定義的完整例子,程式碼如源程式code5_2.xsd所示。

<?xml version="1.0" encoding=gb2312" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="book">
    <xsd:complexType>
    <xsd:sequence>
        <xsd:element name="title" type="xs:string" />
        <xsd:element name="author" type="xs:string"/>
        <xsd:element name="price" type="xs:integer" />
        <xsd:element name="resume" type="xs:string" />
        <xsd:element name="recommendation" type="xs:string" />
        <xsd:element name="publish" minOccurs="0" maxOccurs="unbounded">
            <xsd:complexType>
            <xsd:sequence>
                    <xsd:element name="publisher" type="xs:string" />
                    <xsd:element name="pubdate" type="xs:date" />
            </xsd:sequence>
            </xsd:complexType>
        </xsd:element>
    </xsd:sequence>
    <xsd:attribute name="isbn" type="xs:string" />
    </xsd:complexType>
</xsd:element>
</xsd:schema>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

5.2.2 Schema的使用

符合某個模式的文件稱為例項。例項可以根據特定的模式進行驗證。需要宣告XML文件的Schema例項名稱空間(xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”),並把名稱空間對映到字首xsi。例項與模式之間有多對多的關係。一個模式可以描述多個有效的例項(通過使用不同的根元素型別來實現),同樣,一個例項也可以被多個模式描述。例如一個例項可能擁有多個模式,它們有不同的驗證級別。其中一個模式可能只驗證結構,而另一個模式則根據資料型別來檢查每一個數據項。 
1. Schema的作用 
Schema文件用來驗證XML文件的正確性,用來判斷例項是否符合模式中所描述的所有約束,涉及到檢查例項中所有的元素和屬性。 
Schema主要檢驗如下內容: 
(1) 驗證資料的顯示格式是否正確及是否超出值的範圍; 
(2) 驗證所有必需的資訊都存在; 
(3) 確保不同使用者對文件理解的方式相同。 
除了對XML文件的驗證外,Schema文件還在一定程度上擴充例項: 
(1) 為元素和屬性新增預設值和固定值; 
(2) 使具有簡單型別的元素和屬性值中的空白符規範化。

2. Schema的引用 
一個模式可能由多個模式文件構成。多個模式文件通過包含或匯入機制來形成模式,當其他模式文件與主模式文件具有相同的目標名稱空間時,需要使用包含;當模式文件之間各自擁有不同的目標名稱空間時,需要使用匯入。下面的例子建立一個單獨用來驗證例項的模式文件。 
【例5.3】 關於多個模式文件通過包含實現定義的例子,程式碼如源程式code5_3.xsd所示。

<?xml version="1.0" encoding="gb2312" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://example.org/ord"
targetNamespace="http://example.org/ord">
    <xsd:include schemaLocation="moreBookInfo.xsd"/>
    <xsd:import namespace="http://example.org/ord" schemaLocation="publish.xsd" />
    <!--…-->
</xsd:schema>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

要驗證XML文件,必須指定Schema文件的位置。模式的位置可以利用帶有名稱空間模式的xsi:schemaLocation屬性以及不帶名稱空間XML模式的xsi:noNamespace SchemaLocation 屬性來指定,它們位於根/頂級元素中或XML文件的任何其他元素中。 
當Schema文件不包括targetNamespace屬性時,應當通過XML文件根元素的noNamespace SchemaLocation屬性及W3C的Schema例項名稱空間(xmlns:xsi=“http://www.w3.org /2001/XML Scheam-instance”)來引用XML Schema檔案。針對上面的例項修改如下:

<?xml version="1.0" encoding="gb2312" ?>
<book  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="books.xsd"
isbn="0-764-58007-8">
    <!--…-->
</book>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

然而,如果Schema文件包含了一個targetNamespace 屬性,在XML文件中就將通過schemaLocation屬性而不是noNamespaceSchemaLocation屬性來引用Schema文件。而且,這個屬性所指定的值必須是完整的。它需要包含以空格分開的兩部分,前一部分是URI,這個URI與Schema文件的targetNamespace屬性內部引用的URI是一致的;後一部分是Schema檔案的完整路徑及名稱。另外,XML文件的根元素也必須宣告Schema例項名稱空間(xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”)。Schema文件如下所示:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://tempuri.org/book">
    <!--…-->
</xsd:schema>