使用W3C XML Schema(1)

最近配合做接口测试,需要用到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

让我们从一个描述一本书的简单文档开始:

<? xml version="1.0" encoding="UTF-8" ?>
< 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元素开始:

<? xml version="1.0" encoding="UTF-8" ?>  
< 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 ="title"  type ="xs:string" />  
< xs:element  name ="author"  type ="xs:string" />  

现在,我们必须来处理character 元素了,它是一个复杂类型,注意它的基数(cardinality )是如何定义的:

< xs:element  name ="character"  minOccurs ="0"  maxOccurs ="unbounded" >  
< xs:complexType >  
< xs:sequence >  
.../... 
</ xs:sequence >  
</ xs:complexType >  
</ xs:element >

不像其他的scheme定义语言,W3C XML Schema  允许我们定义一个元素的精密基数(例如:可能的数目),我们可以一起指定minOccurs(最小可能)和maxOccurs (最大可能),这里maxOccurs 设置为unbounded 意思是该节点无最大数目限制,可以任意多。 

我们使用同样的方式指定所有的子节点:

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

我们现在可以声明元素的属性了,一般在最后这样做。似乎并没有什么特别的理由这样做,但是W3C XML Schema工作组已经认为在一种复杂的类型内把一项有关的命令强加到元素列表和属性的定义更简单,并且在元素之后定义属性是更自然的。

< xs:attribute  name ="isbn"  type ="xs:string" />  

就是这样!第一次的设计,有时也被称为“俄罗斯玩偶设计”,紧随我们示例文档的结构。

其中这样的设计的一个关键特点是定义一个上下文中的每个元素和属性,并允许多个事件的同一元素的名称,进行不同的定义。

本例的完整scheme定义如下:

<? xml version="1.0" encoding="utf-8" ?>  
< 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的时候造成了很大的麻烦,甚至在两种技术上无法使用同一个设计指导。

第二种设计基于一个所有在实例文档中可用元素的目录,包括其中的每个元素,例如子元素和属性的列表。这种作用是通过使用元素参考和必须符合范围的参考的属性定义,实现了简单设计:

<? xml version="1.0" encoding="UTF-8" ?>  
< 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:simpleType  name ="nameType" >  
< 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:simpleType  name ="isbnType" >  
< xs:restriction  base ="xs:string" >  
< xs:pattern  value ="[0-9]{10}" />  
</ xs:restriction >  
</ xs:simpleType >

Facets,以及另外两种方式生成一个数据类型(list和union)将在下面的章节介绍。

复杂类型就像我们之前看到的那样被定义,仅仅给一个名称。

定义并且使用命名的数据类型与定义一个类兵器使用它实例化一个对象相似。一种数据类型是一个抽象的概念,可用于定义一个属性或匀速。datatype和属性以及元素的关系类似于类和对象的关系。

完整清单:

<? xml version="1.0" encoding="UTF-8" ?>  
< 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的结构。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值