XML Schema 1.1 简介

来源:http://www.ibm.com/developerworks/cn/xml/x-xml11pt2/?S_TACT=105AGX52&S_CMP=tec-csdn 本系列文章共分 6 个部分,本文是第 2 篇,作者 Neil Delima、Sandy Gao、Michael Glavassevich 和 Khaled Noaman 将深入探讨 XML Schema 1.1 引入的共同约束机制,即新的断言和类型替换(type alternatives)特性。 简介 XML Schema 1.0 同时提供复杂类型和简单类型定义,允许模式作者指定并限制元素的内容和属性值。根据 XML Schema 1.0 规范的描述,复杂类型定义通过提供属性声明对元素进行约束,属性声明可以约束属性的外观和内容,具体方法是将元素限制为空元素或遵循指定的内容模型,比如只包含元素的模型、混合模型,或由内容的简单类型定义确定的简单内容。 常用缩写词 DOM:文档对象模型(Document Object Model) HTML:超文本标记语言(Hypertext Markup Language) W3C:万维网联盟(World Wide Web Consortium) XDM:XPath 2.0 数据模型(XPath 2.0 Data Model) XML:可扩展标记语言(Extensible Markup Language) XSLT:可扩展样式表语言转换(Extensible Stylesheet Language Transformations) 复杂类型定义还定义了一种可以约束类型定义层次结构的机制,它可以确定如何通过扩展或限制,从其他复杂类型派生出不同的复杂类型或简单类型。复杂类型中的替换组可以使用派生类型的元素控制元素替换,另一方面,简单类型可以约束元素和属性内容的字符值。 本文将讨论同现(co-occurrence)约束,这是 XML Schema 1.1 中新引入的一个特性,它不仅可以约束元素和属性的内容,还可以约束它们的存在。 历史回顾 我们在 本系列第一篇文章 中提到,XML Schema 1.0 存在某些限制。除了第一篇文章提到的限制以外,XML 模式作者经常需要强制使用更多复杂规则来判断和限制元素和属性的内容,比如根据属性值限制某些子元素的外观,使子元素的总数不超过特定的值,或者根据子元素的查找范围将它的值设置为有效值。 本系列的其他文章 XML Schema 1.1,第 1 部分:概述对 XML Schema 1.0 的重要改进并深入分析数据类型 不幸的是,XML Schema 1.0 并没有提供实施这些规则的途径。要实现这些约束,您需要执行下面的操作: 编写应用程序级别的代码(在对 XML 模式进行验证之后) 使用样式表检查(即验证后处理) 使用不同的 XML 模式语言,比如 RelaxNG 或 Schematron 由于 XML Schema 1.0 用户社区一直要求提供同现约束检查的支持,因此 XML Schema 1.1 工作组将断言和类型替换的概念引入到 XML Schema 1.1 中,允许 XML 模式作者表达此类约束。 断言 断言可以使 XML 模式作者灵活地控制元素和属性的出现和值。 使用场景 在进一步研究 XML Schema 1.1 如何定义断言之前,首先查看一些使用场景。 根据两个或更多属性的值指定一个约束规则。对于 清单 1 显示的 XML 片段,您可以在 width 和 height 属性之间指定一个规则,使高度永远小于宽度。 清单 1. XML 片段 - 具有两个属性的元素 在属性和元素之间指定一个约束规则。在 清单 2 中,其中一个元素具有一个属性和两个子元素。您可以在属性和子元素之间指定一个规则,使属性的值等于子元素的数量。 清单 2. XML 片段 - 具有一个属性和两个子元素的元素 指定一个约束规则,确定属性之间的次序和选项。对于 清单 3 中定义的元素,可以指定一个规则,根据这条规则,timer 可以具有 time 或 iterations 属性,但不能同时拥有两者。 清单 3. XML 片段 - timer 元素 指定一个规则,将一组元素和属性组成一个模型组。例如,制定一个规则将元素内容限制为 child 或 grandchild,或者两者均具有属性 name 和 dob,这样可以限制 parent 元素(在 清单 4 中定义)的内容。 清单 4. XML 片段 - 一个父元素 在具有混合内容的元素的文本中指定一个约束规则。清单 5 中的 parent 元素具有混合内容。那么可以指定一条规则,将混合内容文本限制为最多只有 10 个字符。 清单 5. XML 片段 - 具有混合内容的父元素 2 children abc xyz 为了满足这些以及其他使用场景,XML Schema 1.1 通过 XML Schema 1.1 断言提供了更具表达性的约束。XML Schema 1.1 中的断言类似于 Schematron 和 RelaxNG 等其他模式语言中使用的断言。 在撰写本文时,您可以对简单和复杂类型指定断言。谓词通过 XPath 2.0 表达式指定,XPath 2.0 表达式是类型指定的断言的一部分。 复杂类型断言 在 XML Schema 1.1 中,复杂类型定义可以包含一个断言模式组件,该组件是一个复杂类型定义的 子元素序列。序列的次序无关紧要。断言约束元素和属性的存在和它们的值。 模式组件包含一个 test 属性(该属性是一个 XPath 表达式属性记录)和一个 annotations 属性。 xs:assert 元素信息项的 test 属性的值是一个 XPath 表达式,其值等于 true 或 false。您可以使用一个特殊的变量 $value 引用被检查的元素或属性的简单内容值。表达式的计算是在父元素的上下文内完成的。XPath 表达式必须是一个有效的 XPath 2.0 表达式,或至少遵循 XML Schema 1.1 规范定义的最小 XPath 子集。 如果指定的 XPath 表达式是无效的,将报告 xpath-valid 错误。如果 xs:assert 没有得到正确指定,那么模式处理程序将报告一个 as-props-correct 错误。如果测试表达式的计算结果为 true 并且没有导致动态的或类型错误,那么则认为元素在逻辑上是有效的。如果表达式计算结果为 false,那么将报告一个常见的 cvc-assertion 错误。 清单 6 是一个复杂类型的例子,其中的断言约束两个属性的值。如果 height 的值小于 width 的值,那么断言表达式的计算结果为 true,否则为 false。 清单 6. 复合类型的断言 - @height < @width 在上面的示例中,我们将 xs:assert 元素信息项定义为 xs:complexType 的直接子元素。我们还可以在使用复杂内容(xs:complexContent)或简单内容(xs:simpleContent)定义复杂类型时对 xs:restriction 或 xs:extension 指定 xs:assert。一个元素要想成为有效的元素,其断言序列中的每个断言的值都必须为 true。这个序列包含对复杂类型定义的所有断言,以及复杂类型的祖先的所有断言。 在 清单 7 中,我们给出了两个复杂类型,baseType 和 derivedType,并且每个类型分别拥有自己的断言。baseType 上的断言检查 mustUnderstand 属性是否在元素中给出,derivedType 上的断言检查 mustUnderstand 属性的值是否是 YES 并且至少给出一个 body 子元素;否则将要求 mustUnderstand 的值为 NO。derivedType 的序列包含两个断言,即来自 baseType 的断言和它本身的断言。要使 message 元素有效,其内容必须按照 complexType 定义那样定义为有效内容,并且所有断言的值必须为 true。 清单 7. 具有复杂内容的复杂类型的断言 在使用简单内容定义复杂类型时,可以指定两种类型的断言。第一种断言充当 facet 并限制简单内容类型(比如,将简单值限制为 7 的倍数),而第二种断言作为整个元素的断言,包括它的属性。由于 xs:simpleContent/xs:restriction 的内容模型的语法并没有区分这两种断言,因此引入了一个新的元素信息项 xs:assertion 来表示一个断言 facet。我们将在下一节讨论简单类型定义断言时介绍 xs:assertion。 简单类型断言 在 XML Schema 1.1 中,和复杂类型一样,xs:simpleType 子元素中的 xs:restriction 元素可以包含 xs:assertion 元素。简单类型中的断言类似于其他简单类型约束 facet。断言简单类型组件表示一组约束 facet,通过令值满足 test 属性值中的 XPath 表达式指定的条件,对简单类型的值空间施加限制。 和复杂类型定义一样,断言是一组被指定为简单类型定义 facet 的一组有序的 xs:assertion 元素序列。断言序列的具体顺序并不重要,因为序列中所有断言的值必须为 true,这样该类型的元素或属性才是有效的。断言模式组件包含一个值属性,这是一个由来自基类型的断言(如果有的话)和派生 simpleType 定义的断言组成的序列。 如 XML Schema 1.1 规范定义的那样,xs:assertion 元素 facet 的 test 属性的值是一个 XPath 2.0 表达式或 XPath 2.0 子集,其值为 true 或 false。计算在父元素的上下文内完成。如果所有断言 facet 有效,那么具有简单内容的元素或属性就是有效的(即每个 xs:assertion 的 test 属性的值为 true,没有出现动态或类型错误)。 在 清单 8 中,我们展示了一个具有简单内容的元素示例,如果该元素的值是 10 的倍数,那么它的断言 facet 则计算为 true。 清单 8. 值为 10 的倍数的具有简单内容的元素 对于限制另一种简单类型的派生简单类型,如果它满足派生类型(及其限制 facet)以及同时属于基类型和派生类型的断言,那么值是有效的。在 清单 9 中,一个字符串值只有在由 3 到 25 个字符组成并且以 “xyz” 为结尾时才是有效的。 清单 8. 对派生简单类型定义的断言 错误消息定制 如前面小节所示,XML Schema 1.1 断言可以使用任何 XPath 2.0 表达式,并且这些表达式可以非常复杂。当断言失败时,非常有必要提供易于理解的错误消息。 模式错误代码 当模式约束被违背后,模式规范要求报告相应的错误代码。比如,如果看到错误代码 cvc-attribute.3,则表明违背了约束 Attribute Locally Valid 的子句 3,表示属性值在类型方面是无效的。 错误代码包含了有关上下文的一些信息(比如元素或属性名、行和列号或涉及的值),因此通常足够用来进行问题诊断。将其应用于断言,如果未能满足断言,那么将报告错误代码 cvc-assertion。即使获得了所有上下文信息,您仍然不知道真正的问题所在以及修复方法,除非您查看模式并尝试理解(可能非常复杂的)XPath 表达式。 Schematron 方法 Schematron 用户(参见 参考资料)常常发现,对违背规则后报告的消息进行定制的能力非常有用(清单 10)。 清单 10. Schematron 规则 On element " ", value of the "min" attribute " " can not be greater than that of the "max" attribute " ". 以下 XML 片段(清单 11)违背了这一规则。 清单 11. 违背 Schematron 规则的 XML 片段 这个片段将生成一条消息:On element "range", value of the "min" attribute "30" can not be greater than that of the "max" attribute "10"。 该方法具有两个重要的优点: 人类可读的错误消息可以被关联到验证规则,从而可以更加轻松地诊断验证失败。 错误消息还可以使用 XPaths 引用被验证的实例的值,提供更多引起违背的原因的信息。在上例中,range、30 和 10 这些信息在每个实例中都不相同。 本地化支持 验证规则可以部署到使用不同本地语言的系统中,并且用户将要求使用不同的人类语言查看错误消息。要使用本地化的消息,Schematron 建议同时使用 diagnostics 属性和 xml:lang 属性,如 清单 12 所示。 清单 12. Schematron 本地化消息示例 A person must have a name. A person must have a name. Une personne doit avoir un nom. Schematron 实现现在可以根据期望的语言选择正确的 diagnostic。 SML 方法 在本地化方面,Schematron 方法仍然不是很完美。在新添了一种语言支持后,需要对 Schematron 规则进行更新,必须同时向 diagnostics 属性添加新的 diagnostic 条目,并添加新的 ID。 Java™ 编程语言使用属性包(property bundles)解决这一问题。在添加了一种新语言后,将引入一个新的属性包,并且只要它遵循某种命名规则,就可以自动发现,而不需要对使用消息的位置进行修改。 Service Modeling Language (SML) 使用 Schematron 作为其众多验证机制中的一种。它引入了 “location ID” 概念(清单 13)允许使用和 Java 环境类似的资源管理策略。 清单 13. 使用 location ID 概念的 SML A person must have a name. locid 属性的类型为 QName。其名称空间可用于定位包(其值可能包含与某人有关的所有错误消息等的信息),而 local name 用于标识错误消息以显示相应的规则。在 清单 14 和 清单 15 中,我们使用英语和法语展示了一些消息属性示例。 清单 14. 英语消息属性片段 nameRequired = A person must have a name. 清单 15. 法语消息属性片段 nameRequired = Une personne doit avoir un nom. 对断言使用错误消息定制 XML Schema 1.1 并没有介绍如何对断言定制错误消息,但是它允许在标注中内嵌特定于应用程序的信息。比如,清单 16 展示了如何在一个标注内的 “appinfo” 元素中包括一个定制的错误消息,并使用 “documentation” 提供有关该消息的额外信息。用户会从 XML Schema 1.1 处理程序使用标注定制断言错误的最佳实践中获益。通常还会包括启用错误消息本地化的机制。 清单 16. 使用标注定制错误消息 Value of the "min" attribute can not be greater than that of the "max" attribute. When this assertion fails, the content of the above "appinfo" is used to produce the error message. 类型替换 XML Schema 1.1 引入了一种称为类型替换(type alternatives)的新机制,允许模式作者在元素声明中指定类型替换。 条件类型分配简介 在 XML Schema 1.0 中,xsi:type 被作为一种类型替换机制引入。要在实例文档中对元素指定 xsi:type,使用派生类型替换声明的类型。如果特别针对 XML Schema 使用设计 XML 词汇表,那么这种机制非常有用,并且词汇表实例需要使用 xsi:type 实现类型替换。然而,如果针对已经具有自己的类型替换的词汇表编写 XML 模式,那么 xsi:type 不会起作用。这种词汇表的实例使用某些其他机制选择类型。一种例子就是 Atom Syndication Format,这是一种用于 Web 提要的 XML 语言。 Atom 允许实例对包含文本结构的元素指定一个 xsi:type 属性。如果给出该属性的话,其值必须为 text、html 或 xhtml 其中之一。所允许的内容由该属性的值决定。由于该属性不是 xsi:type,因此无法编写使用 XML Schema 1.0 语言建模 Atom 的模式。如果选择类型的条件非常复杂,比如 @height < @width(比较两个属性值),则不能简单地使用 xsi:type 在实例中替换它。 为了克服 xsi:type 的缺陷,可以使用类型替换机制。它允许模式作者在元素声明中根据 XPath 表达式的值指定类型替换。在下一小节中我们将使用 Atom 作为例子展示这种方法。 类型替换的原理 在 XML Schema 1.1 中,元素声明的类型表中可以包含一个类型替换组件序列和一个默认类型定义(也是一个类型替换)。在 XML 模式文档中,这些内容被指定为元素声明的 xs:alternative 子元素的序列。类型替换模式组件包含一个 test 属性(一个 XPath 表达式属性记录)、一个类型定义和一个 annotations 属性。 xs:alternative 上的 test 属性的值对应于 test 属性,后者是一个值为 true 或 false 的 XPath 表达式。表达式被限制为 XPath 2.0 的一个子集,特别是那些只选择属性 axis 的表达式。这表示只有当前元素上的属性才能执行 XPath 计算。注意,为计算而构建的 XDM 数据模型并没有包含任何类型定义。这样做是为了避免模式处理程序为判断元素类型而猜测属性类型的情况。除非元素类型已确定,否则无法知晓实际的属性类型。 元素声明中的最后一个 xs:alternative 子元素可以忽略 test 属性。如果给出此属性的话,类型替换就是默认的类型定义。如果没有指定任何此类 xs:alternative,那么元素将声明默认的类型定义。 xs:alternative 的 type 属性的值对应于类型替换模式组件的类型定义属性。如果 test 属性上的 XPath 表达式最终值为 true,那么将选择指定的 type 替换元素中声明的类型。指定的 type 必须派生于声明的类型或称为 xs:error 的特殊简单类型定义(没有有效实例)。xs:error 类型如果满足类型替换的条件,则可以将元素置为无效。 如果元素声明具有类型替换,那么将按照在模式中指定的顺序进行计算。其 XPath 表达式计算为 true 的第一个类型替换使用选择的类型。如果所有 XPath 表达式的值都不是 true,那么将选择默认类型定义作为元素的 type。 现在我们已经介绍了类型替换的原理,现在来看一个示例(清单 17),看看如何使用它编写针对 Atom 的模式。如 上一节 所述,包含文本结构的元素的 type 属性为元素指定了允许的内容。下面的片段展示了如何在 Atom 中为一个 title 元素编写声明。 清单 17. 类型替换 xsd 示例 title 的元素声明有一个 xs:anyType 基类型并且指定了 5 个类型替换。这些类型替换将依次执行计算,直到其中一个 XPath 表达式的值为 true(如果值均不为 true,则选择默认的类型定义)。前三个类型替换根据 type 属性的值(text、html 或 xhtml)选择类型。如果类型属性的值不是这三个值,前三个类型替换的 XPath 表达式将计算为 false。第四个类型替换将检查 type 属性是否存在。如果模式处理程序达到了这个步骤,type(如果该属性存在的话)的值不是 Atom 允许的值。我们将这个替换的类型指定为 xs:error 以表示如果条件得到满足,元素就是无效的。如果没有 XPath 表达式的值是 true,那么选择默认的类型定义(xs:string)。 如 清单 18 所示,title 元素的实例演示了如何选择不同的类型替换。 清单 18. 类型替换 xml 实例元素 My News My <xhtml:em>News</xhtml:em>! My News Oops! Error. 结束语 在本文中,我们概述了 XML Schema 1.1 中的同现约束支持,着重介绍了新增的断言和类型替换特性,这些特性可以进一步限制元素和属性的存在和值。在本系列的第 3 部分中,我们将探讨通配符支持以及它如何允许您改进 XML 模式。 参考资料 学习 您可以参阅本文在 developerWorks 全球网站上的 英文原文。 XML Schema 1.1,第 1 部分:XML Schema 1.1 简介:概述对 XML Schema 1.0 的重要改进并深入分析数据类型 (Neil Delima,Sandy Gao,Michael Glavassevich,Khaled Noaman;deveoperWorks;2008 年 12 月):立即了解在 XML Schema 1.0 基础上的重要改进并深入研究数据类型。 XML 1.0 规范:了解 XML 以及它如何支持在 Web 上提供、接收和处理通用 SGML。 XML Schema Part 1: Structures Second Edition:了解关于 W3C XML 模式语言的更多信息,以及它如何描述 XML 1.0 文档内容(包括利用了 XML Namespace 工具的内容)的结构并对其进行约束。此规范基于 XML Schema Part 2: Datatypes。 XML Schema Part 2: Datatypes Second Edition:了解关于 W3C XML 模式语言中使用的数据类型的信息。 W3C XML Schema Definition Language (XSD) 1.1 Part 1: Structures:查看 W3C XML 模式语言的最新规范。 W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes:查找关于 W3C XML 模式语言中新添加的数据类型的更多信息。 XQuery 1.0:了解关于 XML 查询语言的更多信息,该语言使用 XML 结构来表示跨所有数据类型的查询。 XML Path Language 2.0:了解有关 XPath 语言的更多信息。 Service Modeling Language (SML):了解更多有关如何建模复杂系统和服务的信息。 XSL Transformations (XSLT) Version 2.0:回顾该规范,它定义了 XSLT 2.0 语言的语法和语义。 XQuery 1.0 and XPath 2.0 Data Model (XDM):阅读这个 W3C 规范,它是 XPath 2.0、XSLT 2.0 和 XQuery 语言的数据模型。 Atom Syndication Format:了解更多有关基于 XML 的 Web 内容和元数据连锁格式的信息。 Schematron:了解此语言,判断 XML 文档中是否存在模式。 RELAX NG:研究面向 XML 的模式语言。 IBM XML 认证:了解如何成为 IBM 认证的 XML 和相关技术的开发人员。 XML 技术库:查看 developerWorks XML 专区,获取大量技术文档和技巧、教程、标准以及 IBM 红皮书。 developerWorks 技术活动和网络广播:随时关注这些领域的最新技术。 技术书店:查找关于本文所述主题或其他技术主题的图书。 developerWorks podcasts:收听面向软件开发人员的有趣访问和讨论。 获得产品和技术 The XML Parser for Java (Xerces2-J):尝试这个由 Apache 发布的解析器。 IBM 产品评估试用软件:使用可直接从 developerWorks 下载的 IBM 试用软件构建您的下一个项目,包括来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。 讨论 XML 专区讨论论坛:参与与 XML 相关论坛之一。 developerWorks XML 专区:分享您的想法:阅读完本文之后,在此论坛中发表您的评论和想法。XML 专区编辑主持该论坛并欢迎您的加入。 developerWorks blogs:查看这些 blog 并加入 developerWorks 社区。 作者简介 Neil Delima 是 IBM 多伦多实验室的一位软件开发人员。作为 XML 解析器开发团队的成员,他从事 XML 技术的开发和测试已经超过 7 年了。他是 Apache 的 Xerces-Java 解析器项目的提交者之一,对 W3C DOM 和 XML 1.1 测试套件做出了突出贡献。 Sandy (Shudi) Gao 是 IBM 多伦多软件实验室的一位软件开发人员。他自 2001 年以来就成为了 Apache Xerces XML Parser (Java) 项目的提交者之一,并是该项目的 XML Schema 支持的重要贡献者之一。自 2003 年以来,Sandy 一直是 W3C XML 架构工作组中的 IBM 代表。他对 XML Schema version 1.1 开发做出了突出贡献,并于 2006 年成为了该规范的编辑。Sandy 也是 W3C SML 工作组中的 IBM 代表。 Michael Glavassevich 是 IBM 多伦多实验室的 XML 解析器开发团队的成员。他过去 5 年来一直是 Apache Xerces2 项目的主要贡献者之一,致力于研究 XML Schema、XInclude、JAXP 1.3/1.4 和 DOM Level 3 的实现。Michael 也是开发了 JAXP 1.4 的 JAXP 专家组的 IBM 代表。 Khaled Noaman 是 IBM XML 解析器开发团队的成员之一。过去五年中参与了 Xerces-C++ 解析器的实现,实现了很多解析器特性,包括对 XML Schema Structure 的支持。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值