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"/>
				
		
		
				常用的内建类型有:
		
		
				
						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
						,可以为类型增添更多的细节要求。当
						xml
						文档中对应的元素值违反了这个
						restriction
						就不能通过检验。限制是
						XSD
						里比较常用的内容,我们会看大量的例子。
				
		
		
				
						
								 
						
				
		
		
				对数值大小的限制:(只能取
				
						0
						到
						120
						的闭区间)
				
		
		
				
						<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>
				
		
		
				
						
								 
						
				
		
		
				将值限制在一组既定值内:(类似于枚举
				
						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
						的数字串)
				
		
		
				
						<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> 
				
		
		
				
						
								 
						
				
		
		
				(特定长度的字符数字串,用作密码最合适。)
		
		
				
						<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
						上加内容限制,也可以这样来表达长度)
				
		
		
				
						<xs:element name="password">
				
		
		
				
						<xs:simpleType>
				
		
		
				
						
								  <xs:restriction base="xs:string">
				
		
		
				
						
								    <xs:length value="8"/>
				
		
		
				
						
								  </xs:restriction>
				
		
		
				
						</xs:simpleType>
				
		
		
				
						</xs:element> 
				
		
		
				(设定长度区间)
		
		
				
						<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> 
				
		
		
				(所有空白符都被变为单空格符,首尾空白都被去掉)
		
		
				
						<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>
				
		
		
				
						
								 
						
				
		
		
				只有文本内容的;
		
		
				
						<food type="dessert">Ice cream</food>
				
		
		
				
						
								 
						
				
		
		
				
						
								 
						
				
		
		
				同时包括文本内容和其他元素的。
		
		
				
						<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
						来定义这些元素必须按照这个次序出现,类似于
						sequence
						这样的指示符还有几个,稍后统一介绍。
				
		
		
				
						
								 
						
				
		
		
				定义一个只有文本内容和属性的复合元素,我们需要用一个
				
						simpleContent
						标记,再用一个
						restriction
						或者
						extension
						来限制文本的内容
						:
				
		
		
				
						
								 
						
				
		
		
				
						<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
						的文本内容,而
						attribute
						的
						string
						是限制
						attribute
						本身的内容的。
				
		
		
				对应这个复合模式的
				
						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
						或其他指示符的使用依然有效。你的文本可以穿插于元素之间,但元素的出现次序仍受
						sequence
						的限制。
				
		
		
				
						
								 
						
				
		
		
				记得简单元素里的复用吗,这里同样可以,在
				
						complexType
						标记里加上
						name
						属性,就完成了分离和复用了,对上面所有的复合类型都是通用的。即使写
						xsd
						,也要象
						oop
						语言那样,通过复用来提高修改的效率,同时让页面看起来整洁清晰,至少,我是有着这样的偏执的,呵呵。
				
		
		
				
						
								 
						
				
		
		
				指示符里有以下几种:
		
		
				顺序指示符:
		
		
				
						All 
						所有元素可以不分顺序出现,但只能出现一次。
				
		
		
				
						Choice 
						只有其中一个可以出现
				
		
		
				
						Sequence 
						前面说过了,必须按顺序出现。
				
		
		
				上面的限制可以配合次数指示符加以进一步的限制:
		
		
				
						maxOccurs 
						最多出现次数
				
		
		
				
						minOccurs 
						最少出现次数
				
		
		
				例如:
		
		
				
						<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
						的时候,最大次数还是不能超过
						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
						必须包含已经用顺序指示符包含起来的元素。
				
		
		
				定义后,别的地方可以用
				
						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 阅读(1261) 
评论(7)  编辑  收藏  所属分类: 
Java