隨筆 - 17  文章 - 49  trackbacks - 0
          <2007年1月>
          31123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          常用鏈接

          留言簿(1)

          隨筆分類(17)

          隨筆檔案(17)

          相冊(cè)

          最新隨筆

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          2006 8 23 星期三

          XSD 淺學(xué)筆記

          ?

          簡(jiǎn)單明快的 XSD 的入門(mén)筆記,希望能讓你和我一樣,用半天時(shí)間步入第一道門(mén)檻。

          這一片記錄基礎(chǔ)知識(shí),第二篇會(huì)是些進(jìn)階知識(shí)和總結(jié),然后你就可以寫(xiě)出自己的第一個(gè) XSD 文檔,并用來(lái)驗(yàn)證一個(gè) XML 文檔了。

          XSD 是什么 ?

          一個(gè) xml schema 是用來(lái)描述 xml 文檔結(jié)構(gòu)的,而 XSD xml schema definition 是繼 DTD 后的基于 xml schema 語(yǔ)言,比起 DTD ,它有更好的擴(kuò)展性,增加了功能,更重要的是,它本身就是以 xml 來(lái)寫(xiě)的,而不需要象 DTD 那樣重新學(xué)一門(mén)語(yǔ)言。同時(shí)也可以利用所有對(duì) xml 有效的便利。

          那么為什么要有 schema 呢, xml well-formed 是不足夠的,一個(gè)語(yǔ)法上合法的 xml 仍然可能有錯(cuò)誤,而這些錯(cuò)誤可能導(dǎo)致嚴(yán)重的應(yīng)用后果。

          ?

          基礎(chǔ)概念

          第一印象

          ??????

          以下是一份 xml 文檔

          <?xml version="1.0"?>

          <note>

          <to>Tove</to>

          <from>Jani</from>

          <heading>Reminder</heading>

          <body>Don't forget me this weekend!</body>

          </note>

          ?

          而它對(duì)應(yīng)的一份 xsd 會(huì)是這樣的:

          ?

          <?xml version="1.0"?>

          <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"

          targetNamespace="http://www.w3schools.com"

          xmlns="http://www.w3schools.com"

          elementFormDefault="qualified">

          <xs:element name="note">

          ??? <xs:complexType>

          ????? <xs:sequence>

          ?????? <xs:element name="to" type="xs:string"/>

          ?????? <xs:element name="from" type="xs:string"/>

          ?????? <xs:element name="heading" type="xs:string"/>

          ?????? <xs:element name="body" type="xs:string"/>

          ????? </xs:sequence>

          ??? </xs:complexType>

          </xs:element>

          </xs:schema>

          ?

          簡(jiǎn)單元素:

          簡(jiǎn)單元素是不包含其他元素和屬性的元素。

          定義簡(jiǎn)單元素的語(yǔ)法為:

          <xs:element name="xxx" type="yyy"/>

          常用的內(nèi)建類型有:

          xs:string

          xs:decimal

          xs:integer

          xs:boolean

          xs:date

          xs:time

          可以通過(guò) default 屬性和 fixed 屬性來(lái)修飾。

          <xs:element name="color" type="xs:string" default="red"/>

          <xs:element name="color" type="xs:string" fixed="red"/>

          ?

          屬性:

          只有復(fù)合元素可以有屬性,但屬性本身總是被定義為簡(jiǎn)單類型的。

          <xs:attribute name="xxx" type="yyy"/>

          除了和簡(jiǎn)單元素的定義一樣可以用 default fixed 來(lái)作為屬性之外,還可以用 use 屬性,如果把 use 屬性指定為“ required ”,就說(shuō)明這個(gè)屬性在 xml 文檔中是必須指明的,默認(rèn)情況下屬性的使用是可選的。

          ?

          限制

          當(dāng)一個(gè)元素或者屬性定義了類型( type ), 就可以用 restriction 來(lái)限制這個(gè)類型, restriction 又叫 facet ,可以為類型增添更多的細(xì)節(jié)要求。當(dāng) xml 文檔中對(duì)應(yīng)的元素值違反了這個(gè) restriction 就不能通過(guò)檢驗(yàn)。限制是 XSD 里比較常用的內(nèi)容,我們會(huì)看大量的例子。

          ?

          對(duì)數(shù)值大小的限制:(只能取 0 120 的閉區(qū)間)

          <xs:element name="age">

          <xs:simpleType>

          ? <xs:restriction base="xs:integer">

          ??? <xs:minInclusive value="0"/>

          ??? <xs:maxInclusive value="120"/>

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          將值限制在一組既定值內(nèi):(類似于枚舉 enumeration

          <xs:element name="car">

          <xs:simpleType>

          ? <xs:restriction base="xs:string">

          ??? <xs:enumeration value="Audi"/>

          ??? <xs:enumeration value="Golf"/>

          ??? <xs:enumeration value="BMW"/>

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          限制一定范圍的值:(只能取小寫(xiě)的 26 個(gè)字母)

          <xs:element name="letter">

          <xs:simpleType>

          ? <xs:restriction base="xs:string">

          ??? <xs:pattern value="[a-z]"/>

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          (只能取長(zhǎng)度為 3 的大寫(xiě)字母組合)

          <xs:element name="initials">

          <xs:simpleType>

          ? <xs:restriction base="xs:string">

          ??? <xs:pattern value="[A-Z][A-Z][A-Z]"/>

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          (只能取長(zhǎng)度為 3 的字母,大小寫(xiě)均可)

          <xs:element name="initials">

          <xs:simpleType>

          ? <xs:restriction base="xs:string">

          ??? <xs:pattern value="[a-zA-Z][a-zA-Z][a-zA-Z]"/>

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          (只能取 xyz 中的一個(gè))

          <xs:element name="choice">

          <xs:simpleType>

          ? <xs:restriction base="xs:string">

          ??? <xs:pattern value="[xyz]"/>

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          (只能取長(zhǎng)度為 5 的數(shù)字串)

          <xs:element name="prodid">

          <xs:simpleType>

          ? <xs:restriction base="xs:integer">

          ??? <xs:pattern value="[0-9][0-9][0-9][0-9][0-9]"/>

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          (只能取任意長(zhǎng)度的小寫(xiě)字符串,長(zhǎng)度可以為 0

          <xs:element name="letter">

          <xs:simpleType>

          ? <xs:restriction base="xs:string">

          ??? <xs:pattern value="([a-z])*"/>

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          (有了上一個(gè),你自然也會(huì)猜到這一個(gè):只能取長(zhǎng)度大于 0 的字符串)

          <xs:element name="letter">

          <xs:simpleType>

          ? <xs:restriction base="xs:string">

          ??? <xs:pattern value="([a-z][A-Z])+"/>

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          (選取,其實(shí)和前面的枚舉式功效類似,只能取其一)

          <xs:element name="gender">

          <xs:simpleType>

          ? <xs:restriction base="xs:string">

          ??? <xs:pattern value="male|female"/>

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          (特定長(zhǎng)度的字符數(shù)字串,用作密碼最合適。)

          <xs:element name="password">

          <xs:simpleType>

          ? <xs:restriction base="xs:string">

          ??? <xs:pattern value="[a-zA-Z0-9]{8}"/>

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          (如果不需要在 base 上加內(nèi)容限制,也可以這樣來(lái)表達(dá)長(zhǎng)度)

          <xs:element name="password">

          <xs:simpleType>

          ? <xs:restriction base="xs:string">

          ??? <xs:length value="8"/>

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          (設(shè)定長(zhǎng)度區(qū)間)

          <xs:element name="password">

          <xs:simpleType>

          ? <xs:restriction base="xs:string">

          ??? <xs:minLength value="5"/>

          ??? <xs:maxLength value="8"/>

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          另外,在 xml 里,空白符的情況比較特別,不小心處理就得不到你要的真正效果。

          ?

          (保留所有的空白符)

          <xs:element name="address">

          <xs:simpleType>

          ? <xs:restriction base="xs:string">

          ??? <xs:whiteSpace value="preserve"/>

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          ( 所有的回車,過(guò)行,制表符,長(zhǎng)空白都被替換成相應(yīng)長(zhǎng)度的空格符 )

          <xs:element name="address">

          <xs:simpleType>

          ? <xs:restriction base="xs:string">

          ??? <xs:whiteSpace value="replace"/>

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          (所有空白符都被變?yōu)閱慰崭穹孜部瞻锥急蝗サ簦?/span>

          <xs:element name="address">

          <xs:simpleType>

          ? <xs:restriction base="xs:string">

          ??? <xs:whiteSpace value="collapse"/>

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          最后,上面說(shuō)到的所有的限制,還可以以下面這種格式來(lái)寫(xiě),把 simpleType 加上名字,在元素中的 type 引用這個(gè)名字,好處就是它不再單獨(dú)屬于這個(gè)元素或者屬性的定義了,其他元素可以復(fù)用這個(gè)類型限制,類似于面向?qū)ο缶幊陶Z(yǔ)言中的包裝與復(fù)用。

          <xs:element name="car" type="carType"/>

          <xs:simpleType name="carType">

          ? <xs:restriction base="xs:string">

          ??? <xs:enumeration value="Audi"/>

          ??? <xs:enumeration value="Golf"/>

          ??? <xs:enumeration value="BMW"/>

          ? </xs:restriction>

          </xs:simpleType>

          ?

          復(fù)合元素

          復(fù)合元素的定義就和簡(jiǎn)單元素的剛好相反了,就是包含其他元素或?qū)傩缘脑亍?/span>

          細(xì)分一下有四種:

          空元素;

          <product pid="1345"/>

          ?

          只包含其他元素的;

          <employee>

          <firstname>John</firstname>

          <lastname>Smith</lastname>

          </employee>

          ?

          只有文本內(nèi)容的;

          <food type="dessert">Ice cream</food>

          ?

          ?

          同時(shí)包括文本內(nèi)容和其他元素的。

          <description>

          It happened on <date lang="norwegian">03.03.99</date> ....

          </description>

          而這四個(gè)同時(shí)又都可以有屬性。

          ?

          接下來(lái)我們一一詳細(xì)介紹。

          <product prodid="1345" />

          空元素的定義語(yǔ)法:

          <xs:element name="product">

          ? <xs:complexType>

          ??? <xs:attribute name="prodid" type="xs:positiveInteger"/>

          ? </xs:complexType>

          </xs:element>

          ?

          ?

          <person>

          <firstname>John</firstname>

          <lastname>Smith</lastname>

          </person>

          包含其他元素的復(fù)合元素定義:

          <xs:element name="person">

          ? <xs:complexType>

          ??? <xs:sequence>

          ????? <xs:element name="firstname" type="xs:string"/>

          ????? <xs:element name="lastname" type="xs:string"/>

          ??? </xs:sequence>

          ? </xs:complexType>

          </xs:element>

          xs:sequence 來(lái)定義這些元素必須按照這個(gè)次序出現(xiàn),類似于 sequence 這樣的指示符還有幾個(gè),稍后統(tǒng)一介紹。

          ?

          定義一個(gè)只有文本內(nèi)容和屬性的復(fù)合元素,我們需要用一個(gè) simpleContent 標(biāo)記,再用一個(gè) restriction 或者 extension 來(lái)限制文本的內(nèi)容 :

          ?

          <xs:element name="somename">

          ? <xs:complexType>

          ??? <xs:simpleContent>

          ????? <xs:extension base="basetype">

          ??????? ....

          ??????? ....

          ????? </xs:extension>????

          ??? </xs:simpleContent>

          ? </xs:complexType>

          </xs:element>

          或:

          <xs:element name="somename">

          ? <xs:complexType>

          ??? <xs:simpleContent>

          ????? <xs:restriction base="basetype">

          ??????? ....

          ??????? ....

          ????? </xs:restriction>????

          ??? </xs:simpleContent>

          ? </xs:complexType>

          </xs:element>

          例子:

          <xs:element name="shoesize">

          ? <xs:complexType>

          ??? <xs:simpleContent>

          ????? <xs:extension base="xs:integer">

          ??????? <xs:attribute name="country" type="xs:string" />

          ????? </xs:extension>

          ??? </xs:simpleContent>

          ? </xs:complexType>

          </xs:element>

          注意 extension integer 是限制 shoesize 的文本內(nèi)容,而 attribute string 是限制 attribute 本身的內(nèi)容的。

          對(duì)應(yīng)這個(gè)復(fù)合模式的 xml 可以是:

          <shoesize country="france">35</shoesize>

          ?

          要描述混合的復(fù)合元素:

          <letter>

          Dear Mr.<name>John Smith</name>.

          Your order <orderid>1032</orderid>

          will be shipped on <shipdate>2001-07-13</shipdate>.

          </letter>

          就可以用:

          <xs:element name="letter">

          ? <xs:complexType mixed="true">

          ??? <xs:sequence>

          ????? <xs:element name="name" type="xs:string"/>

          ????? <xs:element name="orderid" type="xs:positiveInteger"/>

          ????? <xs:element name="shipdate" type="xs:date"/>

          ??? </xs:sequence>

          ? </xs:complexType>

          </xs:element>

          只是在包含其他元素的同時(shí)指定 mixed 等于“ true “,而 sequence 或其他指示符的使用依然有效。你的文本可以穿插于元素之間,但元素的出現(xiàn)次序仍受 sequence 的限制。

          ?

          記得簡(jiǎn)單元素里的復(fù)用嗎,這里同樣可以,在 complexType 標(biāo)記里加上 name 屬性,就完成了分離和復(fù)用了,對(duì)上面所有的復(fù)合類型都是通用的。即使寫(xiě) xsd ,也要象 oop 語(yǔ)言那樣,通過(guò)復(fù)用來(lái)提高修改的效率,同時(shí)讓頁(yè)面看起來(lái)整潔清晰,至少,我是有著這樣的偏執(zhí)的,呵呵。

          ?

          指示符里有以下幾種:

          順序指示符:

          All 所有元素可以不分順序出現(xiàn),但只能出現(xiàn)一次。

          Choice 只有其中一個(gè)可以出現(xiàn)

          Sequence 前面說(shuō)過(guò)了,必須按順序出現(xiàn)。

          上面的限制可以配合次數(shù)指示符加以進(jìn)一步的限制:

          maxOccurs 最多出現(xiàn)次數(shù)

          minOccurs 最少出現(xiàn)次數(shù)

          例如:

          <xs:element name="person">

          ? <xs:complexType>

          ??? <xs:sequence>

          ? ???? <xs:element name="full_name" type="xs:string"/>

          ????? <xs:element name="child_name" type="xs:string"

          ????? maxOccurs="10" minOccurs="0"/>

          ??? </xs:sequence>

          ? </xs:complexType>

          </xs:element>

          注意用了 all 的時(shí)候,最大次數(shù)還是不能超過(guò) 1 ,最小可以是 0 1

          ?

          組指示符:

          Group 元素組

          attributeGroup 屬性組

          通過(guò)例子來(lái)看看:

          <xs:group name="persongroup">

          ? <xs:sequence>

          ??? <xs:element name="firstname" type="xs:string"/>

          ??? <xs:element name="lastname" type="xs:string"/>

          ??? <xs:element name="birthday" type="xs:date"/>

          ? </xs:sequence>

          </xs:group>

          定義了一組元素, group 必須包含已經(jīng)用順序指示符包含起來(lái)的元素。

          定義后,別的地方可以用 ref 來(lái)引用:

          <xs:complexType name="personinfo">

          ? <xs:sequence>

          ??? <xs:group ref="persongroup"/>

          ??? <xs:element name="country" type="xs:string"/>

          ? </xs:sequence>

          </xs:complexType>

          ?

          以下這兩個(gè)是對(duì)應(yīng)的 attribute group 的用法:

          <xs:attributeGroup name="personattrgroup">

          ? <xs:attribute name="firstname" type="xs:string"/>

          ? <xs:attribute name="lastname" type="xs:string"/>

          ? <xs:attribute name="birthday" type="xs:date"/>

          </xs:attributeGroup>

          ?

          <xs:element name="person">

          ? <xs:complexType>

          ??? <xs:attributeGroup ref="personattrgroup"/>

          ? </xs:complexType>

          </xs:element>

          ?

          這一篇到這里為止。

          ?

          posted on 2006-08-23 18:25 Ye Yiliang 閱讀(1219) 評(píng)論(7)  編輯  收藏 所屬分類: Java

          FeedBack:
          # re: XSD淺學(xué)筆記 2006-08-25 09:48 hsp
          ~~~~~~~~~~~~~go on  回復(fù)  更多評(píng)論
            
          # re: XSD淺學(xué)筆記 2006-08-25 11:17 yeyiliang
          - -b@hsp
            回復(fù)  更多評(píng)論
            
          # re: XSD淺學(xué)筆記 2006-08-25 16:08 icedee
          不錯(cuò),_^^_  回復(fù)  更多評(píng)論
            
          # re: XSD淺學(xué)筆記 2006-09-07 22:13 stoneshao
          不錯(cuò),狠狠地補(bǔ)了一把;D  回復(fù)  更多評(píng)論
            
          # re: XSD淺學(xué)筆記 2006-10-12 11:46 諤諤
          不錯(cuò),不錯(cuò),希望繼續(xù)努力啊!
            回復(fù)  更多評(píng)論
            
          # re: XSD淺學(xué)筆記 2006-12-22 12:23 Away
          對(duì)于入門(mén)者, 受益了。  回復(fù)  更多評(píng)論
            
          # re: XSD淺學(xué)筆記 2007-01-22 12:01 xkq
          呵呵,寫(xiě)的很好啊 ,繼續(xù)加油哦 !  回復(fù)  更多評(píng)論
            
          主站蜘蛛池模板: 定州市| 武城县| 二连浩特市| 洛隆县| 河源市| 霍林郭勒市| 崇阳县| 遂溪县| 旺苍县| 太康县| 安西县| 南宫市| 耿马| 虹口区| 秀山| 舞阳县| 讷河市| 河东区| 中西区| 临武县| 樟树市| 山阴县| 叙永县| 呼玛县| 搜索| 蓬莱市| 清镇市| 临潭县| 清水河县| 长泰县| 榆林市| 平罗县| 桑日县| 道孚县| 吉水县| 东宁县| 扶余县| 应用必备| 左贡县| 双鸭山市| 邹城市|