与DTD(http://code727.iteye.com/blog/1882877)相比较,Schema是另一种灵活但复杂的XML约束方式。它主要增加了更多的数据类型和结构模式来改进DTD,并使用XML作为约束格式描述。
1.定义Schema约束规则
下面结合一个实例来说明怎样设计Schema约束。
例如,在一个XML文档(templet_test.xml)中,其根元素为templet,它包含的元素结构如下:
<?xml version="1.0" encoding="UTF-8"?> <templet> <bean name="user" class="com.daniele.appdemo.test.domain.User"> <property name="id" type="java:long"/> <property name="name" type="java:string" /> <property name="age" type="java:integer"/> <property name="mail" type="java:string" /> <property name="company" ref="company" /> </bean> <bean name="company" class="com.daniele.appdemo.test.domain.Company"></bean> <description date="2013-06-07">This is a XML Schema example.</description> <author name="daniele" /> <end/> </templet>文档约束规则:
1)bean元素可以有0或无限多个,它只能包含property子元素,并且有一个必选的class属性和一个可选的name属性;
2)property元素可以有0或无限多个,不能包含任何的子元素和文本内容,它只能是bean元素的子元素,并且有一个必选的name属性,以及两个可选的type和ref属性;
3)description元素只能有一个为date类型的属性,它只能包含文本内容,并且只能出现在bean元素的后面;
4)end元素无任何属性、子元素和文本内容,只起到结束标记,并且只能出现在description元素的后面。
由于在templet_test.xml文件的根元素<templet>中没有引入相关的约束文档。因此,针对上述的约束规则在此文档中就是无效的。因此,下一步我们需要创建一个以".xsd"为后缀名的约束文档(schame_test.xsd),然后再将此文档引入到xml文件中。
2.设计Schema约束文档
Schema提供了一系列的组件供用户来设计相关的Schema约束规范。附件为常用标签说明,更多详情请参考
http://www.w3school.com.cn/schema/schema_elements_ref.asp
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.appdemo.daniele.com/schema/templet" targetNamespace="http://www.appdemo.daniele.com/schema/templet"> <!-- 定义XML根元素temple,其内有0个或多个bean元素 --> <xsd:element name="templet"> <!-- complexType元素表示templet是一个复合类型, 属性为false,表示它只能包含元素。 否则,为true(默认)表示同时还可包含文本。 --> <xsd:complexType mixed="false"> <!-- 定义子元素组必须按照其sequence内部定义时的顺序出现一次(默认为有且只出现一次) 次数可通过minOccurs和maxOccurs这两个属性来控制。 --> <xsd:sequence> <!-- 通过ref属性值,引用其他元素作为当前元素的子元素。 如果在schema中定义了目标名称空间,则ref值为"名称空间前缀:子元素名", 否则直接关联子元素名(对应另一个element元素的name属性值)即可。 --> <xsd:element ref="tns:bean" minOccurs="0" maxOccurs="unbounded"/> <xsd:element ref="tns:description" minOccurs="0" maxOccurs="1"/> <xsd:element ref="tns:author" minOccurs="0" maxOccurs="1"/> <xsd:element ref="tns:end" minOccurs="0" maxOccurs="1"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="bean"> <xsd:complexType> <!-- 按顺序出现0次(minOccurs="0")或多次(maxOccurs="unbounded")其内部引用的元素 --> <xsd:sequence minOccurs="0" maxOccurs="unbounded"> <xsd:element ref="tns:property" /> </xsd:sequence> <!-- 定义当前元素具备的属性。 1)name:属性名 2)type:属性值类型 3)use:可选性。 required:必须,optional:可选(默认),prohibited:禁用 当为可选时,可以不用设置该属性。 --> <xsd:attribute name="class" type="xsd:string" use="required" /> <xsd:attribute name="name" type="xsd:string" /> </xsd:complexType> </xsd:element> <xsd:element name="property"> <xsd:complexType mixed="false"> <xsd:attribute name="name" type="xsd:string" use="required" /> <!-- 如果某个属性值具有备选值,则利用<xsd:simpleType> 和<xsd:restriction>这两个元素来替代type属性 --> <xsd:attribute name="type" default="java:string"> <!-- 表示当前属性的值为简单类型 --> <xsd:simpleType> <!--表示当前属性备选值限定的类型 --> <xsd:restriction base="xsd:string"> <!-- 备选值定义 --> <xsd:enumeration value="java:boolean" /> <xsd:enumeration value="java:byte " /> <xsd:enumeration value="java:char" /> <xsd:enumeration value="java:double" /> <xsd:enumeration value="java:float" /> <xsd:enumeration value="java:long" /> <xsd:enumeration value="java:integer" /> <xsd:enumeration value="java:short" /> <xsd:enumeration value="java:string" /> </xsd:restriction> </xsd:simpleType> </xsd:attribute> <xsd:attribute name="ref" type="xsd:string" /> </xsd:complexType> </xsd:element> <!-- description元素只包含文本和属性date --> <xsd:element name="description"> <xsd:complexType> <xsd:simpleContent> <!-- 文本类型为任意字符 --> <xsd:extension base="xsd:string"> <!-- 定义description元素的可选的date属性,其值必须符合日期时间类型 如果不在extension中定义任何attribute,则表示当前元素只能包含文本内容 --> <xsd:attribute name="date" type="xsd:date"/> </xsd:extension> </xsd:simpleContent> </xsd:complexType> </xsd:element> <!-- 定义只有一个必选name属性的author元素,不能有子元素和文本内容 --> <xsd:element name="author"> <xsd:complexType mixed="true"> <xsd:attribute name="name" use="required"/> </xsd:complexType> </xsd:element> <!-- 定义为空的end元素,即不能任何有子元素、文本内容和属性 --> <xsd:element name="end"> <xsd:complexType /> </xsd:element> </xsd:schema>
在.xsd约束文档中,都是以
<schema>来作为根元素的。其中,有两个关键属性需要在设计时设置。
1)
xmlns:规定在此 schema 中使用的一个或多个命名空间的 URI 引用。为避免冲突,可为它分配一个前缀,例如xmlns
:xsd="http://www.w3.org/2001/XMLSchema"。一旦分配了前缀,则在引入schema组件定义约束时,需在这些组件的标签中加上前缀,例如<xsd:element></xsd:element>。
2)
targetNamespace:schema命名空间的URI引用。一般指定为Schema文件所在目录位置的URI即可,例如:http://www.springframework.org/schema/aop。一旦定义了命名空间,则XML实例文件就必须通过命名空间的方式引入它;如果没有定义命名空间,则XML实例文件就只能用无命名空间的方式引入它。
3)xmlns:tns:目标命名空间,不是必须的。当进行Schema组件和类型关联引用时需要用到。
另外还有一些可选属性在设计时可能会使用到。
1)
elementFormDefault
默认值为 "unqualified"。当为默认值
或
无此属性时,则表示在XML文件中使用schema组件时,其标签名称无需加上前缀来进行限定。而属性值为"qualified"时,则需要加上前缀。
2)
attributeFormDefault
默认值为 "unqualified"。当为默认值
或
无此属性时
,则表示在XML文件中使用schema组件时,其属性名称无需加上前缀来进行限定。而属性值为"qualified"时,则需要加上前缀。
3)
version
规定 schema 的版本。
3.引入Schema约束文档
当约束文档设计无误后,就可以按照如下两种方式之一,将相关约束引入到我们的XML实例文档中:
1)名称空间引入
通过这种方式,需要在我们的XML文档根元素中增加如下两个关键属性来实现:
xmlns:命名空间,该属性值应与约束文档中targetNamespace属性值保持一致;
xsi:schemaLocation:约束文档所在的路径。取值为“
命名空间 文档名”,注意命名空间与文档名之间应保持有一个空格或换行符。
2)无名称空间引入
这种方式只能引入没有目标命名空间的约束文档(即被引用的约束文档中没有定义
targetNamespace属性)。通过如下关键的属性来实现:
xsi:noNamespaceSchemaLocation:即约束文档相对于当前XML实例文档的路径。因此,这种方式只适用于本地引入的需求。
如上两种方式都还需要一个关键属性来支持,即
xmlns:xsi,这是Schema解析器所需要的,其值通常为“
http://www.w3.org/2001/XMLSchema-instance”,表示遵循W3C的Schema约束规范。
引入约束后的XML文档(templet_test.xml)的内容如下:
<?xml version="1.0" encoding="UTF-8"?> <!-- 无命名空间引入 --> <!-- <templet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schame_test.xsd"> --> <!-- 命名空间引入 --> <templet xmlns="http://www.appdemo.daniele.com/schema/templet" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.appdemo.daniele.com/schema/templet schame_test.xsd"> <bean name="user" class="com.daniele.appdemo.test.domain.User"> <property name="id" type="java:long"/> <property name="name" type="java:string" /> <property name="age" type="java:integer"/> <property name="mail" type="java:string" /> <property name="company" ref="company" /> </bean> <bean name="company" class="com.daniele.appdemo.test.domain.Company"></bean> <description date="2013-06-07">This is a XML Schema example.</description> <author name="daniele" /> <end/> </templet>
在Eclipse环境中,当我们键入"Alt + /"的组合键后,将会在弹出的提示框中显示备选的元素和属性等。