2006
年
8
月
23
日
星期三
XSD 淺學(xué)筆記
簡單明快的 XSD 的入門筆記,希望能讓你和我一樣,用半天時間步入第一道門檻。
這一片記錄基礎(chǔ)知識,第二篇會是些進(jìn)階知識和總結(jié),然后你就可以寫出自己的第一個 XSD 文檔,并用來驗證一個 XML 文檔了。
Any 元素
如同其名字那樣,這個元素就是可以替代任何元素,相當(dāng)于一個占位符,給予了 xsd 文件一個擴(kuò)展的空間。
<xs:element name="person">
? <xs:complexType>
??? <xs:sequence>
????? <xs:element name="firstname" type="xs:string"/>
????? <xs:element name="lastname" type="xs:string"/>
????? <xs:any minOccurs="0"/>
??? </xs:sequence>
? </xs:complexType>
</xs:element>
在上面的 xsd 里我們放置了 any 元素,給了 minOccurs 指示符,然后再看下面這個元素類型:
<?xml version="1.0" encoding="ISO-8859-1"?>
<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="children">
? <xs:complexType>
??? <xs:sequence>
????? <xs:element name="childname" type="xs:string"
????? maxOccurs="unbounded"/>
??? </xs:sequence>
? </xs:complexType>
</xs:element></xs:schema>
將上面的元素放置到 any 的位置里,將是合法的:
<?xml version="1.0" encoding="ISO-8859-1"?><persons xmlns="http://www.microsoft.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:SchemaLocation="http://www.microsoft.com family.xsd
http://www.w3schools.com children.xsd"><person>
<firstname>Hege</firstname>
<lastname>Refsnes</lastname>
<children>
? ???? ?<childname>Cecilie</childname>
</children>
</person>
<person>
<firstname>Stale</firstname>
<lastname>Refsnes</lastname>
</person>
</persons>
同樣的還有 anyAttribute 標(biāo)記,對應(yīng)的是屬性的占位符。用法是類似的。
元素替換
有時候我們需要讓某個位置的元素的名字可以換成另外一個,這個時候用元素替換,看下例:
<xs:element name="name" type="xs:string"/>
<xs:element name="navn" substitutionGroup="name"/>
<xs:complexType name="custinfo">
? <xs:sequence>
??? <xs:element ref="name"/>
? </xs:sequence>
</xs:complexType>
<xs:element name="customer" type="custinfo"/>
<xs:element name="kunde" substitutionGroup="customer"/>
使用 subsitutionGroup 以及要替換的元素的名字,那么就可以使得下面的 xml 是合法的:
<customer>
? <name>John Smith</name>
</customer>
或
<kunde>
? <navn>John Smith</navn>
</kunde>
如果你確認(rèn)某個元素絕對不想被替換,也可以聲明這一點(diǎn),用 block
<xs:element name="name" type="xs:string" block="substitution"/>
<xs:element name="navn" substitutionGroup="name"/>
<xs:complexType name="custinfo">
? <xs:sequence>
??? <xs:element ref="name"/>
? </xs:sequence>
</xs:complexType>
<xs:element name="customer" type="custinfo" block="substitution"/>
<xs:element name="kunde" substitutionGroup="customer"/>
上面的聲明將使得:
<kunde>
? <navn>John Smith</navn>
</kunde>
會是非法的。
http://www.w3schools.com/schema/schema_example.asp
寫一個
XSD
文檔
就象寫一份 xml 文檔一樣,首先聲明根元素為 schema ,給予名稱空間等等。
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">......
</xs:schema>
接下來就是把你前面所學(xué)的,關(guān)于定義元素和類型的知識應(yīng)用進(jìn)來,寫一份簡單快捷的 xsd ,例如下面的這一份:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="shiporder">
?<xs:complexType>
? <xs:sequence>
?? <xs:element name="orderperson" type="xs:string"/>
?? <xs:element name="shipto">
??? <xs:complexType>
???? <xs:sequence>
????? <xs:element name="name" type="xs:string"/>
????? <xs:element name="address" type="xs:string"/>
????? <xs:element name="city" type="xs:string"/>
????? <xs:element name="country" type="xs:string"/>
???? </xs:sequence>
??? </xs:complexType>
?? </xs:element>
?? <xs:element name="item" maxOccurs="unbounded">
??? <xs:complexType>
???? <xs:sequence>
????? <xs:element name="title" type="xs:string"/>
????? <xs:element name="note" type="xs:string" minOccurs="0"/>
????? <xs:element name="quantity" type="xs:positiveInteger"/>
????? <xs:element name="price" type="xs:decimal"/>
???? </xs:sequence>
??? </xs:complexType>
?? </xs:element>
? </xs:sequence>
? <xs:attribute name="orderid" type="xs:string" use="required"/>
?</xs:complexType>
</xs:element>
</xs:schema>
稍微要注意的是 attribute 必須出現(xiàn)在一個 complexType 的最后位置,先元素,后屬性。
這樣的文檔完全可行,但會有些難讀,再次利用重構(gòu)的方法,把簡單元素,屬性,復(fù)合元素分別獨(dú)立出來,再用引用標(biāo)記 ref 來組合:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- definition of simple elements -->
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
<!-- definition of attributes -->
<xs:attribute name="orderid" type="xs:string"/>
<!-- definition of complex elements -->
<xs:element name="shipto">
?<xs:complexType>
? <xs:sequence>
?? <xs:element ref="name"/>
?? <xs:element ref="address"/>
?? <xs:element ref="city"/>
?? <xs:element ref="country"/>
? </xs:sequence>
?</xs:complexType>
</xs:element>
<xs:element name="item">
?<xs:complexType>
? <xs:sequence>
?? <xs:element ref="title"/>
?? <xs:element ref="note" minOccurs="0"/>
?? <xs:element ref="quantity"/>
?? <xs:element ref="price"/>
? </xs:sequence>
?</xs:complexType>
</xs:element>
<xs:element name="shiporder">
?<xs:complexType>
? <xs:sequence>
?? <xs:element ref="orderperson"/>
?? <xs:element ref="shipto"/>
?? <xs:element ref="item" maxOccurs="unbounded"/>
? </xs:sequence>
? <xs:attribute ref="orderid" use="required"/>
?</xs:complexType>
</xs:element>
</xs:schema>
這樣看起來清晰很多,而且方便修改和復(fù)用。
更進(jìn)一步的,把類型獨(dú)立出來,給予名字,這樣所有的元素都直接復(fù)用類型:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="stringtype">
?<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="inttype">
?<xs:restriction base="xs:positiveInteger"/>
</xs:simpleType>
<xs:simpleType name="dectype">
?<xs:restriction base="xs:decimal"/>
</xs:simpleType>
<xs:simpleType name="orderidtype">
?<xs:restriction base="xs:string">
? <xs:pattern value="[0-9]{6}"/>
?</xs:restriction>
</xs:simpleType>
<xs:complexType name="shiptotype">
?<xs:sequence>
? <xs:element name="name" type="stringtype"/>
? <xs:element name="address" type="stringtype"/>
? <xs:element name="city" type="stringtype"/>
? <xs:element name="country" type="stringtype"/>
?</xs:sequence>
</xs:complexType>
<xs:complexType name="itemtype">
?<xs:sequence>
? <xs:element name="title" type="stringtype"/>
? <xs:element name="note" type="stringtype" minOccurs="0"/>
? <xs:element name="quantity" type="inttype"/>
? <xs:element name="price" type="dectype"/>
?</xs:sequence>
</xs:complexType
><xs:complexType name="shipordertype">
?<xs:sequence>
? <xs:element name="orderperson" type="stringtype"/>
? <xs:element name="shipto" type="shiptotype"/>
? <xs:element name="item" maxOccurs="unbounded" type="itemtype"/>
?</xs:sequence>
?<xs:attribute name="orderid" type="orderidtype" use="required"/>
</xs:complexType>
<xs:element name="shiporder" type="shipordertype"/>
</xs:schema>
好了,現(xiàn)在你可以自己動手開始寫自己的 xsd 了。如果遇到問題,可以到這份東西的英文原出處仔細(xì)弄個究竟:
http://www.w3schools.com/schema/default.asp
全篇完。