XML Schema幫你建模(1)
發(fā)布時(shí)間:2008-09-07 閱讀數(shù): 次 來(lái)源:網(wǎng)樂(lè)原科技
XML Schema是2001年5月正式發(fā)布的W3C(萬(wàn)維網(wǎng)聯(lián)盟)的推薦標(biāo)準(zhǔn),經(jīng)過(guò)數(shù)年的大規(guī)模討論和開(kāi)發(fā)如今終于奠定下來(lái),成為全球公認(rèn)的XML環(huán)境下首選的數(shù)據(jù)建模工具。
由于XML是SGML(標(biāo)準(zhǔn)通用標(biāo)示語(yǔ)言)的一個(gè)子集,它也繼承了SGML用于建模的DTD。使用DTD的好處是可以利用大量現(xiàn)有的DTD工具,使得開(kāi)發(fā)應(yīng)用代價(jià)維持在一個(gè)相對(duì)較低的水平。然而,DTD有不少缺陷:
1. DTD是基于正則表達(dá)式的,描述能力有限;
2. DTD沒(méi)有數(shù)據(jù)類(lèi)型的支持,在大多數(shù)應(yīng)用環(huán)境下能力不足;
3. DTD的約束定義能力不足,無(wú)法對(duì)XML實(shí)例文檔做出更細(xì)致的語(yǔ)義限制;
4. DTD不夠結(jié)構(gòu)化,重用的代價(jià)相對(duì)較高;
5. DTD并非使用XML作為描述手段,而DTD的構(gòu)建和訪問(wèn)并沒(méi)有標(biāo)準(zhǔn)的編程接口,無(wú)法使用標(biāo)準(zhǔn)的編程方式進(jìn)行DTD維護(hù)。
XML Schema正是針對(duì)這些DTD的缺點(diǎn)而設(shè)計(jì)的,它完全使用XML作為描述手段,具有很強(qiáng)的描述能力、擴(kuò)展能力和處理維護(hù)能力。
XML Schema簡(jiǎn)介
XML Schema的主要目的是用來(lái)定義一類(lèi)XML文檔(一個(gè)XML Application)。因此,模式的“實(shí)例文檔”形式常常被用于描述一個(gè)與特定XML Schema相一致的XML文檔。事實(shí)上,文檔實(shí)例和Schema文檔都不是必須要以文檔的形式存在,它們可以以在應(yīng)用之間傳遞的字節(jié)流的形式存在,或者作為一個(gè)數(shù)據(jù)庫(kù)記錄及XML的“信息項(xiàng)”的集合存在。然而為了簡(jiǎn)化入門(mén),我們總是把實(shí)例和模式看作文檔或者文件,認(rèn)為它們總以文檔實(shí)例或是模式文檔的形式存在。
這里我們將結(jié)合一個(gè)實(shí)例來(lái)對(duì)XML Schema進(jìn)行簡(jiǎn)單的概述,希望大家通過(guò)閱讀本節(jié)的內(nèi)容初步掌握的使用方法和XML Schema文檔實(shí)例的具體語(yǔ)義。XML Schema是Web Services技術(shù)中需要使用的一個(gè)基本工具,然而并不是XML Schema的所有特性都會(huì)被廣泛地使用,因此,本文將不對(duì)XML Schema規(guī)范做系統(tǒng)的介紹。
在介紹XML Schema語(yǔ)法之前,先來(lái)考慮一個(gè)XML實(shí)例文檔po.xml。它描述了一個(gè)由家庭產(chǎn)品采購(gòu)/支付應(yīng)用生成的家庭產(chǎn)品購(gòu)買(mǎi)訂單(參閱代碼1)。
<!--代碼 1 po.xml,購(gòu)買(mǎi)訂單的XML實(shí)例文檔-->
<?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>
這個(gè)購(gòu)買(mǎi)訂單由一個(gè)跟元素purchaseOrder及其子元素shipTo、billTo、comment和items組成。這些子元素(除了comment)也依次包含了其它的一些子元素。
葉子元素包含的是一個(gè)數(shù)字而不是任何子元素,如USPrice這樣的子元素。元素如果包含子元素或者是帶有屬性的,被稱為復(fù)合類(lèi)型;反之元素如果僅僅包含數(shù)字、字符串或者其它數(shù)據(jù)等,但不包含任何子元素的,則被稱為簡(jiǎn)單類(lèi)型。在這個(gè)實(shí)例文檔中,復(fù)合類(lèi)型和一些簡(jiǎn)單類(lèi)型是在購(gòu)買(mǎi)定單的模式文檔中定義的,而其它一些標(biāo)準(zhǔn)的簡(jiǎn)單類(lèi)型則是作為XML Schema內(nèi)置的簡(jiǎn)單類(lèi)型的形式出現(xiàn)的。
在研究這個(gè)實(shí)例文檔的購(gòu)買(mǎi)訂單模式文檔之前,先介紹一下購(gòu)買(mǎi)訂單實(shí)例文檔和模式文檔之間的聯(lián)系。一個(gè)實(shí)例文檔實(shí)際上并不一定需要引用模式文檔,當(dāng)然,在事實(shí)上的使用中,很多實(shí)例文檔確實(shí)引用了模式文檔,為了使入門(mén)變得更加簡(jiǎn)單,一開(kāi)始我們選擇不引用。同時(shí)假設(shè)任何實(shí)例文檔的處理器即使從購(gòu)買(mǎi)訂單實(shí)例文檔中得不到任何信息,也能夠正確地進(jìn)行購(gòu)買(mǎi)訂單模式文檔的處理。
購(gòu)買(mǎi)訂單模式文檔
在代碼2,給出了購(gòu)買(mǎi)訂單的模式文檔。文件po.xsd在給出解釋之前,大家可以使用XML的知識(shí)去嘗試?yán)斫膺@個(gè)模式文檔。
<!--代碼 2 po.xsd,購(gòu)買(mǎi)訂單的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>
購(gòu)買(mǎi)訂單模式文檔由一個(gè)schema元素和一系列子元素組成,大多數(shù)子元素為element、complexType和simpleType,這些決定了實(shí)例文檔中元素的表現(xiàn)方式和內(nèi)容,大家最好能熟記element、complexType、simpleType這幾個(gè)元素,這些將是我們一直需要使用的幾個(gè)元素。
同時(shí),可以通過(guò)使用出現(xiàn)在schema元素中的命名空間聲明xmlns:xsd="http://www.w3.org/2001/XMLSchema",使得模式文檔中的每一個(gè)元素都有一個(gè)與XML Schema命名空間相聯(lián)系的命名空間前綴“xsd:”。盡管在語(yǔ)法上,可以使用任意的前綴形式,但是,命名空間前綴“xsd:”被約定用于表示XML Schema命名空間。由于使用同樣的前綴,所以同樣的關(guān)聯(lián)就會(huì)出現(xiàn)在內(nèi)置的簡(jiǎn)單類(lèi)型的名字中,例如xsd:string。這種形式關(guān)聯(lián)的目的是用來(lái)表示當(dāng)前的元素或簡(jiǎn)單類(lèi)型是屬于XML Schema語(yǔ)言的內(nèi)置定義的,而不是屬于模式文檔作者自己的詞匯表的。為了在這里清楚并且簡(jiǎn)單地表示,我們僅提及元素的名字和簡(jiǎn)單類(lèi)型名,而忽略它們的前綴“xsd:”。