最近配合做接口测试,需要用到schema验证,以前没接触过schema,原来还是很好用滴;转一个找到的不错资料,收藏。
转载地址:http://blog.chinaunix.net/space.php?uid=9195812&do=blog&id=2006657
W3C XML Schema 定义语言是描述和约束XML文档内容的XML语言,W3C推荐使用W3C XML Schema。
本文介绍了如何使用W3C XML Schema,还包括了对Schema数据类型和结构的完整参考。
第一个Schema
让我们从一个描述一本书的简单文档开始:
< book isbn ="0836217462" >
< title >
Being a Dog Is a Full-Time Job
</ title >
< author > Charles M. Schulz </ author >
< character >
< name > Snoopy </ name >
< friend-of > Peppermint Patty </ friend-of >
< since > 1950-10-04 </ since >
< qualification >
extroverted beagle
</ qualification >
</ character >
< character >
< name > Peppermint Patty </ name >
< since > 1966-08-22 </ since >
< qualification > bold, brash and tomboyish </ qualification >
</ character >
</ book >
要为这份文档写一份scheme,可以从它的结构和定义我们看到的每个元素开始,我们现在从xs:schema元素开始:
< xs:schema
xmlns:xs ="http://www.w3.org/2001/XMLSchema" >
.../...
</ xs:schema >
定义从schema 元素开始,它也包括了目标名称空间的定义和几个默认选项,我们会在下面章节中看到它们。
为了匹配book 元素标签,我们定义一个叫做book的元素。这个元素具有属性而无文字子节点,因此我们认为它是一个complexType (因为另一个数据类型simpleType 是只包括数据值而没有子节点或者属性),book元素的子节点使用sequence 元素进行定义:
< xs:element name ="book" >
< xs:complexType >
< xs:sequence >
.../...
</ xs:sequence >
.../...
</ xs:complexType >
</ xs:element >
sequence 定义了顺序的子元素,接下来的章节还会探讨另外两个同样的元素:choice和all。
现在,我们来定义title和author元素为简单类型——因为它们没有包含属性和非文本元素,并且可以在一个退化的元素element 内部直接描述。类型(xs:string)是被预先加了XML scheme相关的名称空间前缀,表示为预定义的XML scheme数据类型:
< xs:element name ="author" type ="xs:string" />
现在,我们必须来处理character 元素了,它是一个复杂类型,注意它的基数(cardinality )是如何定义的:
< xs:complexType >
< xs:sequence >
.../...
</ xs:sequence >
</ xs:complexType >
</ xs:element >
不像其他的scheme定义语言,W3C XML Schema 允许我们定义一个元素的精密基数(例如:可能的数目),我们可以一起指定minOccurs(最小可能)和maxOccurs (最大可能),这里maxOccurs 设置为unbounded 意思是该节点无最大数目限制,可以任意多。
我们使用同样的方式指定所有的子节点:
< xs:element name ="friend-of" type ="xs:string" minOccurs ="0" maxOccurs ="unbounded" />
< xs:element name ="since" type ="xs:date" />
< xs:element name ="qualification" type ="xs:string" />
我们现在可以声明元素的属性了,一般在最后这样做。似乎并没有什么特别的理由这样做,但是W3C XML Schema工作组已经认为在一种复杂的类型内把一项有关的命令强加到元素列表和属性的定义更简单,并且在元素之后定义属性是更自然的。
就是这样!第一次的设计,有时也被称为“俄罗斯玩偶设计”,紧随我们示例文档的结构。
其中这样的设计的一个关键特点是定义一个上下文中的每个元素和属性,并允许多个事件的同一元素的名称,进行不同的定义。
本例的完整scheme定义如下:
< xs:schema xmlns:xs ="http://www.w3.org/2001/XMLSchema" >
< xs:element name ="book" >
< xs:complexType >
< xs:sequence >
< xs:element name ="title" type ="xs:string" />
< xs:element name ="author" type ="xs:string" />
< xs:element name ="character" minOccurs ="0" maxOccurs ="unbounded" >
< xs:complexType >
< xs:sequence >
< xs:element name ="name" type ="xs:string" />
< xs:element name ="friend-of" type ="xs:string" minOccurs ="0"
maxOccurs ="unbounded" />
< xs:element name ="since" type ="xs:date" />
< xs:element name ="qualification" type ="xs:string" />
</ xs:sequence >
</ xs:complexType >
</ xs:element >
</ xs:sequence >
< xs:attribute name ="isbn" type ="xs:string" />
</ xs:complexType >
</ xs:element >
</ xs:schema >
下面的章节探讨了如何细分模式设计,以使它们更具可读性和可维护性。
分层 Schema
因为以往的设计方法很简单,它会导致内嵌设计变得深奥,使之难以可读并且当文 件复杂的时候难以维护。另外一个不利的地方是,XML和DTD在结构上差别很大,给人和机器在想将DTD转换到XML Scheme的时候造成了很大的麻烦,甚至在两种技术上无法使用同一个设计指导。
第二种设计基于一个所有在实例文档中可用元素的目录,包括其中的每个元素,例如子元素和属性的列表。这种作用是通过使用元素参考和必须符合范围的参考的属性定义,实现了简单设计:
< xs:schema xmlns:xs ="http://www.w3.org/2001/XMLSchema" >
<!-- definition of simple type elements -->
< xs:element name ="title" type ="xs:string" />
< xs:element name ="author" type ="xs:string" />
< xs:element name ="name" type ="xs:string" />
< xs:element name ="friend-of" type ="xs:string" />
< xs:element name ="since" type ="xs:date" />
< xs:element name ="qualification" type ="xs:string" />
<!-- definition of attributes -->
< xs:attribute name ="isbn" type ="xs:string" />
<!-- definition of complex type elements -->
< xs:element name ="character" >
< xs:complexType >
< xs:sequence >
< xs:element ref ="name" />
< xs:element ref ="friend-of" minOccurs ="0" maxOccurs ="unbounded" />
< xs:element ref ="since" />
< xs:element ref ="qualification" />
<!-- the simple type elements are referenced using
the "ref" attribute -->
<!-- the definition of the cardinality is done
when the elements are referenced -->
</ xs:sequence >
</ xs:complexType >
</ xs:element >
< xs:element name ="book" >
< xs:complexType >
< xs:sequence >
< xs:element ref ="title" />
< xs:element ref ="author" />
< xs:element ref ="character" minOccurs ="0" maxOccurs ="unbounded" />
</ xs:sequence >
< xs:attribute ref ="isbn" />
</ xs:complexType >
</ xs:element >
</ xs:schema >
使用元素或属性的引用某种程度上好克隆一个对象相似。元素或者属性首先被定义,然后在该文档的其他地方可以通过引用机制被复制,同样对象也可以被克隆。这两个元素(或属性)那么就是同一个类的两个实例。
下面的章节我们将讲述怎样定义“types”这种类,它允许我们复用元素定义。
定义命名类型
我们已经看到,当我们需要他们时,我们可以定义元素和属性,首先创建并引用它们(目录)。 W3C XML Schema 给我们第3 个机制, 将确定数据类型(用于PCDATA元素的简单类型或者属性或者仅用于元素的复杂类型)使用这种类型去定义我们的属性和元素。
这是通过给simpleType 和complexType 元素命名实现的,并且在元素和属性定义之外定位它们。我们也会借此机会,以显示我们如何通过在数据类型上定义约束新建一个数据类型。
例如,要定义一个名为nameType的数据类型,其为最大32个字符的字符串,我们会这样写:
< xs:restriction base ="xs:string" >
< xs:maxLength value ="32" />
</ xs:restriction >
</ xs:simpleType >
simpleType 元素中的name属性值为新数据类型的名称。restriction 元素表示通过应用一个约束,该数据类型源自于W3C XML Schema 名称空间(基础属性)的数据类型。例如,通过现在可能值的数字。这个maxLength 元素,即所谓的facet,说明这个约束是一个最大长度为32字符的约束条件。
另外一个功能强大的facet是pattern元素,它定义了一个必须匹配的正则表达式。例如,如果我们不关心“-”字符,我们可以定义ISBN数据类型为10个数字,因此:
< xs:restriction base ="xs:string" >
< xs:pattern value ="[0-9]{10}" />
</ xs:restriction >
</ xs:simpleType >
Facets,以及另外两种方式生成一个数据类型(list和union)将在下面的章节介绍。
复杂类型就像我们之前看到的那样被定义,仅仅给一个名称。
定义并且使用命名的数据类型与定义一个类兵器使用它实例化一个对象相似。一种数据类型是一个抽象的概念,可用于定义一个属性或匀速。datatype和属性以及元素的关系类似于类和对象的关系。
完整清单:
< xs:schema xmlns:xs ="http://www.w3.org/2001/XMLSchema" >
<!-- definition of simple types -->
< xs:simpleType name ="nameType" >
< xs:restriction base ="xs:string" >
< xs:maxLength value ="32" />
</ xs:restriction >
</ xs:simpleType >
< xs:simpleType name ="sinceType" >
< xs:restriction base ="xs:date" />
</ xs:simpleType >
< xs:simpleType name ="descType" >
< xs:restriction base ="xs:string" />
</ xs:simpleType >
< xs:simpleType name ="isbnType" >
< xs:restriction base ="xs:string" >
< xs:pattern value ="[0-9]{10}" />
</ xs:restriction >
</ xs:simpleType >
<!-- definition of complex types -->
< xs:complexType name ="characterType" >
< xs:sequence >
< xs:element name ="name" type ="nameType" />
< xs:element name ="friend-of" type ="nameType" minOccurs ="0"
maxOccurs ="unbounded" />
< xs:element name ="since" type ="sinceType" />
< xs:element name ="qualification" type ="descType" />
</ xs:sequence >
</ xs:complexType >
< xs:complexType name ="bookType" >
< xs:sequence >
< xs:element name ="title" type ="nameType" />
< xs:element name ="author" type ="nameType" />
< xs:element name ="character" type ="characterType" minOccurs ="0" />
<!-- the definition of the "character" element is
using the "characterType" complex type -->
</ xs:sequence >
< xs:attribute name ="isbn" type ="isbnType" use ="required" />
</ xs:complexType >
<!-- Reference to "bookType" to define the
"book" element -->
< xs:element name ="book" type ="bookType" />
</ xs:schema >
下面讲的是分组、排序以及衍生如何用来实现进一步的复用以及介绍scheme的结构。