1 / 78

第 3 章 XML 模式语言 ( XML Schema )

第 3 章 XML 模式语言 ( XML Schema ). DTD 的缺点 : (1) 缺少数据类型和命名空间的支持 ; (2) 语法规则过于简单以至描述能力有限 ; (3) 使用非 XML 的格式等。 XML Schema 是专用于 XML 的模式语言,功能更强大 , 且本身即为 XML 格式。. 3.1 XML 模式语言. XML 模式语言是指用来描述 XML 结构、数据内容、相关约束等方面特征的语言。 XML 模式语言的种类很多: ISO Schematron

kueng
Download Presentation

第 3 章 XML 模式语言 ( XML Schema )

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第3章 XML 模式语言 (XML Schema)

  2. DTD的缺点: (1)缺少数据类型和命名空间的支持; (2)语法规则过于简单以至描述能力有限; (3)使用非 XML 的格式等。 • XML Schema是专用于XML的模式语言,功能更强大,且本身即为XML格式。

  3. 3.1 XML 模式语言 • XML 模式语言是指用来描述 XML 结构、数据内容、相关约束等方面特征的语言。 • XML 模式语言的种类很多: • ISO Schematron • XDR (XML-DATA Reduced) • XML Schema • RELAX NG 一种非常独特的 XML 模式语言,无论是结合其他模式语言或者单独使用都具有强大的功能。Schematron 语言允许直接表达规则,而不需要创建完整的语法基础设施。 W3C 的正式推荐标准,提供了 XML 模式声明的完整语法、丰富的数据结构等,目前已成为应用最广泛的 XML 模式语言。 是由 Microsoft 公司提出的 XML 简化模式语言,作为 W3C 在讨论 XML Schema 工作草案过程中提出的一种过渡性 Schema 语言,XDR 已经被业界普遍认可,得到许多产品(例如,MS-BiztalkServer、MS-SQLServer、MS-Office)的广泛支持。 一种基于语法的 XML 模式语言,可用于描述、定义和限制 XML 词汇表。它以简洁性和表达能力著称,并且具有良好的可扩展性。

  4. XML Schema 的特征 1 • 与 DTD 相比,XML Schema 具有特征: • 一致性:XMLSchema 利用 XML 的基本语法规则来定义其文档结构,从而使 XML的模式和实例定义达到统一;继承了XML的自描述性和可扩展性,使其更具有可读性和灵活性。 • 完备性:XML Schema 对 DTD 进行了扩充,引入了数据类型、命名空间,并且支持对其他 XML Schema 的引用,从而使其具备较强的模块性; • 规范性和准确性:XML Schema 提供了更加规范和完备的机制来约束 XML 文档。XML Schema 的语义更加准确,可以完成一些 DTD 不能完成的定义,如对元素出现次数的约束等。

  5. XML Schema 的特征 2 • 面向对象特征:XML Schema 中引入了许多成熟的面向对象机制(比如继承性和多态性),使得数据模式在应用中更加灵活。 • 扩展性:DTD 所描述的文档结构是非常严格的(closed),没有显式声明的内容绝不允许在 XML 实例数据中出现;而 XML Schema 则提供了一些扩展机制(open),允许在事先无法准确描述数据模式的情况下,在 XML 实例数据中根据需要添加相关的数据。

  6. 3.1.2 XML Schema 的一个简单示例 • student.xsd • XML Schema 文件的后缀名通常为 .xsd • XML Schema 文件是一个特殊的 XML 文件。 • 注意根元素及命名空间。

  7. 实例 XML 文档 <?xml version="1.0" encoding="UTF-8"?> <student> <name>XiaoWang</name> <gender>男</gender> <no>123</no> <telephone>010-12345678</telephone> <gpa>80</gpa> </student> <?xml version="1.0" encoding="UTF-8"?> <student xsi:noNamespaceSchemaLocation="student.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> ...... </student>

  8. XML Schema 中的“注释”元素 • 在 W3C XML Schema 文件中,推荐使用 xsd:annotation 元素来增加注释内容,xsd:annotation 元素可以包含两个子元素 xs:appinfo 和 xs:documentation。 • 前者用于表示计算机应用程序处理的注释,而后者则表示供开发人员阅读的注释。 • 这两个子元素是 W3C XML Schema 中唯一的混合内容模型的元素,其中可以包含任何文本和子元素。

  9. 3.2 XML Schema 中的数据类型 • 元素是其中最为重要的组成部分,一个 XML 文档中可能不包含任何属性或者文本数据,但是必须包含元素(至少包含一个根元素)。 • XML Schema 中的数据类型实际上主要是针对 XML 元素而言的,换句话说,是针对各种元素的内容及其结构的。

  10. 元素的类型 • 在 W3C 的 XML Schema 规范中,将元素分为两类: • 简单类型:不包含任何子元素和属性的元素。换句话说,简单类型的元素只能包含文本内容,或者为不包含属性的空元素(文本内容为空)。 • 复杂类型:包含子元素和/或属性的元素(其中属性的声明包含在元素的复杂类型定义中)。 <lastname> Jack </lastname> <description/> <product pid="1345"/> <food type="dessert">Ice cream</food>

  11. 有关元素类型的说明 • 简单类型元素只能包含文本内容,而复杂类型元素除了包含子元素和/或属性之外,也可以包含文本内容。 • “文本内容”并不是指的字符串数据类型,在 XML Schema 规范中定义了 44 种简单数据类型 ,“文本内容”可以是这些简单数据类型中的任何一种(甚至还可以是派生的简单数据类型)。 • 比如: <xsd:element name=“orderid” type=“xsd:integer”/>。 <orderid>1032</orderid> 正确 <orderid>abc</orderid> 错误

  12. 3.2.1 XML Schema 的内置数据类型 • anyType 是 XML Schema 中所有数据类型(包括简单类型和复杂类型、内置数据类型和用户定义数据类型)的基础类型,如果拿 Java 语言来做个类比,那么 xsd:anyType 类似于 Java 中的 java.lang.Object。 • anyType 分为“简单类型”和“复杂类型”。 • anyType 是一种实际的、可用的数据类型,而不仅仅只是在 XML Schema 数据类型层次结构中作为抽象的根节点。 比如: • <element name="Currency" type="anyType" /> • <Currency> USD </Currency> • <Currency><dollars>100</dollars></Currency> • anySimpleType 是所有简单数据类型的基础类型。 • anySimpleType 也是一种实际的、可用的数据类型,它是所有简单数据类型的根节点,与 anyType 不同的是,它只能表示标量数据。 • 比如: • <element name="Currency" type="anySimpleType" /> • <Currency> USD </Currency> • <Currency><dollars>100</dollars></Currency> • 内置基本数据类型(Primitive Datatype):这些类型是独立存在的,而不是在其他数据类型的基础上定义的。比如数学上的十进制数,定义为 decimal。 • 在 XML Schema 规范中,一共定义了 19 中内置的基本数据类型,它们可以单独使用、或者作为其他派生数据类型(包括内置派生数据类型和用户派生数据类型)的基础类型。 • 内置派生数据类型(Derived Datatype):这些内置类型的定义依赖于其他的数据类型(即内置基本数据类型)。 • 比如 decimal 和 nonNegativeInteger,可以将后者理解为满足某种条件(非负整数)的 decimal,实际上,decimal 是 XML Schema 中所有十进制数值类型的基础类型。

  13. 常用数据类型(字符串类型)

  14. 常用数据类型(数值类型 )

  15. 常用数据类型(日期、时间和其他类型 )

  16. 3.2.2 XML Schema 中的派生简单数据类型 • 仅使用44种基本数据类型仍然是不够的。比如,假设希望定义一个 email 数据类型、或者 telephone 数据类型,用于约束合法的 email 和 telephone 数据,那又该怎么做呢? • XML Schema 为此提供了自定义简单数据类型、复杂数据类型的机制,以便用户在需要的时候对 XML Schema 类型系统进行扩充。 • 可以通过几种不同的方法(通过限制、列表、或者组合)自定义简单数据类型。

  17. 1. 通过限制(restriction)派生简单数据类型 • 通过限制的方式派生简单数据类型的语法格式如下所示,下面的两种形式分别声明了一个无名的、以及一个命名的(名为 SimpleTypeName)简单数据类型: <xsd:simpleType> <xsd:restriction base="BaseType"> ... facets descriptions ... </xsd:restriction> </xsd:simpleType> 或者: <xsd:simpleType name="SimpleTypeName"> <xsd:restriction base="BaseType"> ... facets descriptions ... </xsd:restriction> </xsd:simpleType>

  18. a). 通过设置最大值或最小值,对数值类型取值的范围进行限制 <xsd:elementname="MyIntegerElement" type="MyInteger"/> <xsd:simpleType name="MyInteger"> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="0"/> <xsd:maxInclusive value="100"/> </xsd:restriction> </xsd:simpleType> <xsd:elementname="MyIntegerElement"> <xsd:simpleType> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="0"/> <xsd:maxInclusive value="100"/> </xsd:restriction> </xsd:simpleType> </xsd:element> 与 minInclusive 和 maxInclusive 相对应,还有 minExclusive 和 maxExclusive,后面两种限制方面的取值空间为开区间。

  19. b). 通过枚举,将取值空间限制为一组合法的取值 <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:enumeration value="Audi"/> <xsd:enumeration value="Golf"/> <xsd:enumeration value="BMW"/> </xsd:restriction> </xsd:simpleType> 这个数据类型的基本类型是 xsd:string,在此基础上,通过xsd:enumeration 列举出了若干个合法的取值。

  20. c). 通过给定一个正则表达式,限制字符串内容的模式 <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:pattern value="[a-z]"/> </xsd:restriction> </xsd:simpleType> <xsd:simpleType name="Telephone"> <xsd:restriction base="xsd:string"> <xsd:pattern value="(\d{4}-\d{8})|(\d{3}-\d{8})|(\d{4}-\d{7})"/> </xsd:restriction> </xsd:simpleType>

  21. 正则表达式中的各种元符号(metacharacter)及其描述 1

  22. 正则表达式中的各种元符号(metacharacter)及其描述 2

  23. 正则表达式的使用 • 比如我们希望建立一个 email 数据类型,以便验证在用户提交的 XML 文档中,指定的元素中包含合法的电子邮件地址: • 很多文本编辑器(如 EditPlus、Word)中进行内容查找时,可以使用正则表达式作为条件。另外 Java 语言中提供了java.util.regex,其中包含 Matcher 和 Pattern 两个类、以及其他的接口等,借助正则表达式的强大功能,从而极大地增强了面向对象的 Java 语言的文本处理能力。 ([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5}) somthing@someserver.com firstname.lastname@mailserver.domain.comsomename@server.domain-com 可以参考网站 http://regexlib.com

  24. d). 限制文本内容中字符串的长度 • 可以使用 length、maxLength 和 minLength 等 Schema 元素来限制文本内容的长度。 <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:length value="8"/> </xsd:restriction> </xsd:simpleType> <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:minLength value="5"/> <xsd:maxLength value="8"/> </xsd:restriction> </xsd:simpleType>

  25. e). 限制文本内容中数值的位数和小数位数 • 可以使用 totalDigits 和 fractionDigits 来限制数值的总位数和小数位数。 <xsd:simpleType> <xsd:restriction base="xsd:decimal"> <xsd:totalDigits value="4"/> <xsd:fractionDigits value="2"/> </xsd:restriction> </xsd:simpleType>

  26. XML Schema 中的各种限制方面 Facet

  27. <xsd:simpleType name="minInclusive"> <xsd:restriction base="xsd:float"> <xsd:minInclusive value="10"/> </xsd:restriction> </xsd:simpleType> <xsd:simpleType name="minInclusive2"> <xsd:restriction base="minInclusive"> <xsd:minInclusive value="0"/> </xsd:restriction> </xsd:simpleType> 有关通过限制派生简单数据类型的几项说明 • ①.在通过限制派生简单数据类型时,必须注意取值空间的有效性。 • ②.对于所有的限制方面,不允许在进行限制的同时扩大基本数据类型的值空间。 <xsd:simpleType> <xsd:restriction base="xsd:int"> <xsd:totalDigits value="1"/> <xsd:minInclusive value="10"/> <xsd:maxInclusive value="100"/> </xsd:restriction> </xsd:simpleType>

  28. 2.通过列表(List)派生简单数据类型 • 仅有前面介绍的简单类型仍然不够,假设我们希望在某个元素的内容中包含由若干个整数值组成的文本,比如: • 通过列表进行派生,实际上就是在定义列表中每个项目的具体类型的基础上,允许多个项目构成一个列表(其中使用空格进行分隔)。 <MyIntegers>100 101 102</MyIntegers>

  29. 通过列表进行派生 1 <xsd:simpleType name="integerList"> <xsd:list itemType="xsd:integer"/> </xsd:simpleType> <xsd:simpleType name="myIntegerList"> <xsd:list> <xsd:simpleType> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="100"/> </xsd:restriction> </xsd:simpleType> </xsd:list> </xsd:simpleType>

  30. 通过列表进行派生 2 <xsd:simpleType name="integerGE100"> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="100"/> </xsd:restriction> </xsd:simpleType> <xsd:simpleType name="myIntegerList"> <xsd:list itemType="integerGE100"/> </xsd:simpleType> <xsd:simpleType name="myIntegerList"> <xsd:list> <xsd:simpleType> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="100"/> </xsd:restriction> </xsd:simpleType> </xsd:list> </xsd:simpleType> <xsd:simpleType name="FourIntegerList"> <xsd:restriction base="myIntegerList"> <xsd:length value="4"/> </xsd:restriction> </xsd:simpleType>

  31. 3. 通过合并(Union)派生简单数据类型 • 通过列表派生简单数据类型,使得我们可以在文本内容中加入多个项目(比如多个整数值),但是无论有多少个项目,它们的数据类型必须一致,这是通过列表方式派生简单数据类型的基本要求。 • 假设在一个 student 元素中存放学生各门功课(语、数、外三门)的成绩: <student1>70 80 90</student1> <student2>70 80 N/A</student2>

  32. 通过合并进行派生 <xsd:simpleType name="integerOrDate"> <xsd:union memberTypes="xsd:integer xsd:date"/> </xsd:simpleType> <xsd:simpleType name="myIntegerUnion"> <xsd:union> <xsd:simpleType> <xsd:restriction base="xsd:integer"/> </xsd:simpleType> <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:enumeration value="N/A"/> </xsd:restriction> </xsd:simpleType> </xsd:union> </xsd:simpleType>

  33. 3.2.3 XML Schema 中的派生复杂数据类型 • 下面的两种形式分别声明了一个无名的、以及一个命名的(名为 ComplexTypeName)复杂数据类型: <xsd:complexType> ...... </xsd:complexType > 或者: <xsd:complexType name="ComplexTypeName"> ...... </xsd:complexType>

  34. 复杂数据类型的几种情况 • 只包含属性、不包含子元素和文本内容; • 比如:<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>

  35. 1. 空元素(只包含属性、不包含子元素和文本内容) • 对于包含属性的空元素,定义过程非常简单,只需定义所需的属性及其数据类型即可。 <xsd:complexType name="ComplexType"> <xsd:attribute name="Att1Name" type="someSimpleType1"/> <xsd:attribute name="Att2Name" type="someSimpleType2"/> ...... </xsd:complexType>

  36. 2. 只包含子元素,不包含文本内容(可能包含属性) • XML Schema 中提供了几种不同的容器(对应于不同的分组模式),以便表示其中子元素的出现顺序,它们分别是 xsd:sequence、xsd: choice、xsd:all。

  37. xsd:sequence • 表示序列,即元素必须按照声明的顺序出现。 <xsd:complexType name="studentType"> <xsd:sequence> <xsd:element name="firstname" type="xsd:string"/> <xsd:element name="lastname" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:element name="student" type="studentType"/> • 表示序列,即元素必须按照声明的顺序出现。 • 元素的声明必须放在某个容器中,而不能直接出现在 xsd:complexType 元素中,即使是只有一个子元素。

  38. xsd: choice • 表示从所包含的内容中选择其一。 <xsd:complexType name="PurchaseOrderType"> <xsd:sequence> <xsd:choice> <xsd:sequence> <xsd:element name="shipTo" type="USAddress"/> <xsd:element name="billTo" type="USAddress"/> </xsd:sequence> <xsd:element name="singleUSAddress" type="USAddress"/> </xsd:choice> <xsd:element name="items" type="Items"/> </xsd:sequence> <xsd:attribute name="orderDate" type="xsd:date"/> </xsd:complexType> <xsd:element name="PurchaseOrder" type="PurchaseOrderType"/>

  39. xsd:all • 表示其中所包含的内容不分先后顺序。 <xsd:complexType name="studentType"> <xsd:all> <xsd:element name="firstname" type="xsd:string"/> <xsd:element name="lastname" type="xsd:string"/> </xsd: all> </xsd:complexType> <xsd:element name="student" type="studentType"/>

  40. 3. 只包含文本内容和属性,不包含子元素 • 对于这种类型的元素,只包含简单内容(文本和属性),在进行声明时,XML Schema 中引入了一个新的元素,称为 simpleContent(用于表示“文本”、或者“文本+属性”)。

  41. 声明方法

  42. 示例 1 • 比如,shoesize 元素只包含属性 country 和文本内容(具体的 shoesize 大小,一个整数值): <shoesize country="france">35</shoesize> <xsd:element name="shoesize"> <xsd:complexType> <xsd:simpleContent> <xsd:extension base="xsd:integer"> <xsd:attribute name="country" type="xsd:string"/> </xsd:extension> </xsd:simpleContent> </xsd:complexType> </xsd:element>

  43. xsd:extension 和 xsd:restriction • 使用 xsd:extension 元素,可以对基础类型进行扩展;但元素文本内容的类型实际上只能由 base 属性所指定的类型来决定,在 xsd:extension 元素中,只能定义与属性有关的内容(xsd:attribute、xsd:anyAttribute、xsd:attributeGroup)。 • 使用 xsd:restriction 元素,可以对基础类型进行限制;与 xsd:extension 一样,元素文本的类型是由 base 属性所指定的类型来决定,但是可以在 xsd:restriction 元素中使用各种限制方面(Facet)对其进行限制;

  44. 4. 同时包含子元素和文本(可能包含属性) • 与 DTD 中一样,我们将这种类型的元素所包含的内容称为混合内容。 • 要定义这种复杂数据类型,需要使用 complexType 的 mixed 属性。

  45. 示例 <letter letter_id="123"> Dear Mr.<name>John Smith</name>. Your order <orderid>1032</orderid> will be shipped on <shipdate>2007-07-13</shipdate>. </letter> <xsd:element name="letter"> <xsd:complexType mixed="true"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="orderid" type="xsd:positiveInteger"/> <xsd:element name="shipdate" type="xsd:date"/> </xsd:sequence> <xsd:attribute name="letter_id" type="xsd:positiveInteger"/> </xsd:complexType> </xsd:element>

  46. 3.2.4 有关类型声明的完整语法 • 前面介绍了如何声明简单数据类型和复杂数据类型,主要使用的是下面的简单的语法形式: <xsd:simpleType name="simpleTypeName"> ...... </xsd: simpleType> 以及: <xsd:complexType name="complexTypeName"> ...... </xsd:complexType>

  47. 3.2.4.1 simpleType 元素的属性 <simpleType final = (#all | List of (list | union | restriction)) id = ID name = NCName> Content: (annotation?, (restriction | list | union)) </simpleType> • final 属性的值表示该数据类型不允许进行的操作的列表,比如本示例中,不允许使用列表对该类型进行派生。但是可以直接使用该类型。 • #all 表示不能对该类型进行任何操作。

  48. 3.2.4.2 complexType 元素的属性 <complexType abstract = boolean : false block = (#all | List of (extension | restriction)) final = (#all | List of (extension | restriction)) id = ID mixed = boolean : false name = NCName> Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))) </complexType> • abstract 属性表示该复杂类型是一个虚类型,只能用作其他类型的父类型。

  49. XML Schema 中的面向对象特性(OO Features)——多态性 <xsd:complexType name="Class1" abstract="true"> <xsd:sequence> <xsd:element name="Class1_subelement" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="Class11"> <xsd:complexContent> <xsd:extension base="Class1"> <xsd:attribute name="Class11Attr" type="xsd:string"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> <xsd:element name="obj" type="Class1"/> <obj Class11Attr="att" xsi:type="Class11"> <Class1_subelement>123</Class1_subelement> </obj>

  50. block 属性 • 如果不希望使用多态性,可以使用 complexType 的 block 属性(它的取值可能为 #all、extension、restriction)。 • extension 和 restriction,分别表示禁止使用任何通过扩展/限制而派生的子类型的实例来代替声明为父类的元素。 • block 和 final 属性是有区别的,因为即使 block=“#all”,仍然可以派生新的子类型,而 final =“#all”则表示禁止派生。对于 block 来说,#all 表示禁止使用任何子类型的实例来代替声明为父类的元素。

More Related