隨筆 - 17  文章 - 49  trackbacks - 0
          <2006年10月>
          24252627282930
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          常用鏈接

          留言簿(1)

          隨筆分類(17)

          隨筆檔案(17)

          相冊

          最新隨筆

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          2006 8 23 星期三

          XSD 淺學筆記

          ?

          簡單明快的 XSD 的入門筆記,希望能讓你和我一樣,用半天時間步入第一道門檻。

          這一片記錄基礎知識,第二篇會是些進階知識和總結,然后你就可以寫出自己的第一個 XSD 文檔,并用來驗證一個 XML 文檔了。

          XSD 是什么 ?

          一個 xml schema 是用來描述 xml 文檔結構的,而 XSD xml schema definition 是繼 DTD 后的基于 xml schema 語言,比起 DTD ,它有更好的擴展性,增加了功能,更重要的是,它本身就是以 xml 來寫的,而不需要象 DTD 那樣重新學一門語言。同時也可以利用所有對 xml 有效的便利。

          那么為什么要有 schema 呢, xml well-formed 是不足夠的,一個語法上合法的 xml 仍然可能有錯誤,而這些錯誤可能導致嚴重的應用后果。

          ?

          基礎概念

          第一印象

          ??????

          以下是一份 xml 文檔

          <?xml version="1.0"?>

          <note>

          <to>Tove</to>

          <from>Jani</from>

          <heading>Reminder</heading>

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

          </note>

          ?

          而它對應的一份 xsd 會是這樣的:

          ?

          <?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>

          ?

          簡單元素:

          簡單元素是不包含其他元素和屬性的元素。

          定義簡單元素的語法為:

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

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

          xs:string

          xs:decimal

          xs:integer

          xs:boolean

          xs:date

          xs:time

          可以通過 default 屬性和 fixed 屬性來修飾。

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

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

          ?

          屬性:

          只有復合元素可以有屬性,但屬性本身總是被定義為簡單類型的。

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

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

          ?

          限制

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

          ?

          對數(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>

          ?

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

          <xs:element name="letter">

          <xs:simpleType>

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

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

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          (只能取長度為 3 的大寫字母組合)

          <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>

          ?

          (只能取長度為 3 的字母,大小寫均可)

          <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 中的一個)

          <xs:element name="choice">

          <xs:simpleType>

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

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

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          (只能取長度為 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>

          ?

          (只能取任意長度的小寫字符串,長度可以為 0

          <xs:element name="letter">

          <xs:simpleType>

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

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

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          (有了上一個,你自然也會猜到這一個:只能取長度大于 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>

          ?

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

          <xs:element name="gender">

          <xs:simpleType>

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

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

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          ?

          (特定長度的字符數(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)容限制,也可以這樣來表達長度)

          <xs:element name="password">

          <xs:simpleType>

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

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

          ? </xs:restriction>

          </xs:simpleType>

          </xs:element>

          (設定長度區(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>

          ?

          ( 所有的回車,過行,制表符,長空白都被替換成相應長度的空格符 )

          <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>

          ?

          最后,上面說到的所有的限制,還可以以下面這種格式來寫,把 simpleType 加上名字,在元素中的 type 引用這個名字,好處就是它不再單獨屬于這個元素或者屬性的定義了,其他元素可以復用這個類型限制,類似于面向對象編程語言中的包裝與復用。

          <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>

          ?

          復合元素

          復合元素的定義就和簡單元素的剛好相反了,就是包含其他元素或屬性的元素。

          細分一下有四種:

          空元素;

          <product pid="1345"/>

          ?

          只包含其他元素的;

          <employee>

          <firstname>John</firstname>

          <lastname>Smith</lastname>

          </employee>

          ?

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

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

          ?

          ?

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

          <description>

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

          </description>

          而這四個同時又都可以有屬性。

          ?

          接下來我們一一詳細介紹。

          <product prodid="1345" />

          空元素的定義語法:

          <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>

          包含其他元素的復合元素定義:

          <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 來定義這些元素必須按照這個次序出現(xiàn),類似于 sequence 這樣的指示符還有幾個,稍后統(tǒng)一介紹。

          ?

          定義一個只有文本內(nèi)容和屬性的復合元素,我們需要用一個 simpleContent 標記,再用一個 restriction 或者 extension 來限制文本的內(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)容的。

          對應這個復合模式的 xml 可以是:

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

          ?

          要描述混合的復合元素:

          <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>

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

          ?

          記得簡單元素里的復用嗎,這里同樣可以,在 complexType 標記里加上 name 屬性,就完成了分離和復用了,對上面所有的復合類型都是通用的。即使寫 xsd ,也要象 oop 語言那樣,通過復用來提高修改的效率,同時讓頁面看起來整潔清晰,至少,我是有著這樣的偏執(zhí)的,呵呵。

          ?

          指示符里有以下幾種:

          順序指示符:

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

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

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

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

          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ù)還是不能超過 1 ,最小可以是 0 1

          ?

          組指示符:

          Group 元素組

          attributeGroup 屬性組

          通過例子來看看:

          <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)用順序指示符包含起來的元素。

          定義后,別的地方可以用 ref 來引用:

          <xs:complexType name="personinfo">

          ? <xs:sequence>

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

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

          ? </xs:sequence>

          </xs:complexType>

          ?

          以下這兩個是對應的 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) 評論(7)  編輯  收藏 所屬分類: Java

          FeedBack:
          # re: XSD淺學筆記 2006-08-25 09:48 hsp
          ~~~~~~~~~~~~~go on  回復  更多評論
            
          # re: XSD淺學筆記 2006-08-25 11:17 yeyiliang
          - -b@hsp
            回復  更多評論
            
          # re: XSD淺學筆記 2006-08-25 16:08 icedee
          不錯,_^^_  回復  更多評論
            
          # re: XSD淺學筆記 2006-09-07 22:13 stoneshao
          不錯,狠狠地補了一把;D  回復  更多評論
            
          # re: XSD淺學筆記 2006-10-12 11:46 諤諤
          不錯,不錯,希望繼續(xù)努力啊!
            回復  更多評論
            
          # re: XSD淺學筆記 2006-12-22 12:23 Away
          對于入門者, 受益了。  回復  更多評論
            
          # re: XSD淺學筆記 2007-01-22 12:01 xkq
          呵呵,寫的很好啊 ,繼續(xù)加油哦 !  回復  更多評論
            
          主站蜘蛛池模板: 涿州市| 阳西县| 禹州市| 保康县| 沙湾县| 合川市| 邻水| 奉新县| 海林市| 姜堰市| 阿城市| 赤城县| 沅陵县| 辽阳市| 马关县| 南城县| 玛纳斯县| 枣阳市| 大理市| 白城市| 临朐县| 周至县| 南涧| 临海市| 大理市| 旅游| 昌图县| 临沭县| 双流县| 武汉市| 曲靖市| 霍城县| 鲁甸县| 瓮安县| 英山县| 金门县| 湾仔区| 耿马| 云安县| 瑞安市| 沙湾县|