图2-2 XML文档及其可选的相关模式
当同一个元素出现在多个地方时,创建这种模式文档的结构就很有用了。XML模式中没有文档实例中文档元素的概念,因此可以包含多个全局元素。不利之处是,有效性解析器可以接受任意一个元素作为文档元素。
2.定义数据类型
上面的XML模式样本只使用了XML模式推荐标准中的内建简单数据类型。也可以自己定义数据类型。例如,如果一个属性只能有yes或no值,那么自定义一个反映这种情况的数据类型或许有用:
上述声明创建了一个名为YesNoType的简单类型元素。该元素基于xs:string数据类型并且有两个可选值:yes或no。
一旦定义后,声明就可以使用内建数据类型同样的方式使用这个数据类型:
如果需要将这个数据类型用于其他的模式,那么可以像在网站中使用服务器端包含文件那样包含样式。数据类型可以保存在一个模式文档中,并使用
这个数据类型定义被保存于customDataType.xsd文件中。在模式文档中,可以使用下列声明来对它进行引用:
customDataType.xsd和dvd_include.xsd文件可以在下载的资源文件中找到。
注解 引入的模式有时称为架构型模式,因为它的目的是提供作为文档有效性验证依据的文档模式的构造单
元。 3.模式结构
前面介绍了创建模式的三种不同方法:在一个元素中声明所有的元素和属性(Russian doll),使用ref数据类型定义全局元素,以及定义自命名的数据类型。
总地来说,如果只针对某个文档定义模式,Russian doll方法比较合适。如果创建的模式可能用于几个不同的文档实例,那么至少为其中的某些元素使用全局定义将会比较灵活方便。
如果希望某个元素总是以同样的名字被引用,那就将它定义为一个元素。如果不同名字的元素有可能具有相同的结构时,就定义一个数据类型。
举个例子,如果有个文档包含一个可能具有多种用途的地址,例如邮政地址、街道地址和投递地址。一种方法可能是在整个文档中重用元素。然而,如果希望同样的元素结构具有不同的元素名称,那么定义一个全局性的address数据类型会更好,它可以用于
4.模式和命名空间
XML模式的主题非常丰富,可以用一整本书来进行讨论。但现在我们只讨论模式与命名空间的关系。
定义一个模式时,可能也会定义一个其实例文档所在的命名空间。可以通过使用
模式内对这些元素的引用都必须使用这个命名空间。这可避免将之定义为XML模式的默认命名空间所带来的麻烦。下面是一个例子:
在这个例子中,elementFormDefault属性设置成了qualified,还将attributeFormDefault属性设置为unqualified。这些属性说明了本地定义的元素和属性是否在命名空间内有效。本地定义的元素是指在复合类型元素中定义的元素。
将elementFormDefault属性设置为qualified并不意味着文档实例中的本地元素也是有效的。attributeFormDefault的设置确保属性被当成属于其包含元素所有的命名空间里的属性一样对待。这在XML中是默认的。
5.将模式指定到文档
在建立了模式文档后,需要从实例文档中对其加以引用,这样XML有效性解析器就可对文档进行有效性验证。这可以通过schemaLocation或noNamespaceSchemaLocation属性来指定。如果没有目标命名空间,就使用后一个属性。
这些属性是W3C控制的命名空间的一部分,被称为XML模式实例命名空间。通常以前缀xsi进行引用。这需要在文档实例内部对命名空间进行声明。
由于模式文档不在命名空间内部,因此使用noNamespaceSchemaLocation属性作为文档元素的例子:
完整的文档保存为dvd_schema.xml,可以在下载的文件中找到。
注意xsi:noNamespaceSchemaLocation属性的语法。在本例中,该文档使用了一个对模式文档的本地引用,但它本可使用一个有效的URI来从互联网上寻找到模式文档。
如果使用了schemaLocation属性,那么其值将由一个命名空间URI加上该命名空间的XML模式文档的物理位置的URI组成。可以对文档元素进行重写使其引用一个命名空间:
如上例所示,使用本地引用或是有效的URI都是可以的。值得注意的是,属性xsi:schemaLocation的值可以是任意数量的URI对,其第一部分是命名空间的URI,而第二部分是相关XML模式的位置。这使得一个文档实例可以被关联到多个XML模式文档。
6.模式和实体声明
DTD的一个优点在于,它们可提供一种定义个性化的实体引用的方法。如前所述,这在使用XML模式来声明XML词汇时是不行的。在使用XML模式时,如需要包括实体引用,那么也可以在文档实例中包含一个DTD。XML模式用于有效性验证,而DTD则用于声明实体引用:
2.2.3 DTD与模式的比较
前面已经介绍了DTD和XML模式是如何确定XML词汇的规则的。虽然这两种类型的文档都起着相同的作用,但它们之间还是有一些不同。下面对它们做一个比较:
l DTD和XML模式都可对XML文档的结构进行定义,以便通过一个有效性解析器来对文档进行检查; l DTD中可以定义实体,而在XML模式中却不行; l XML模式中可以为字符数据指定数据类型,而DTD不行; l XML模式中可以定义个性化的数据类型,而DTD却不能;
l XML模式支持从一个数据类型中引申另一个数据类型,而DTD却不支持数据类型的引申; l XML模式支持命名空间,而DTD却不支持命名空间;
l XML模式提供
l XML模式使用XML标记语法,因而可以使用标准XML处理工具创建和修改它们而DTD并不遵循XML词汇的构造规则;
l 由于DTD的语法简练,因而其文档较小。XML模式的语法通常不够简练,因而产生的文件较大; l XML模式语言比DTD规范更新,它弥补了DTD的一些不足之处。
DTD和XML模式是很多模式语言中的两种。在某些情况下,也许需要考虑使用其他类型的模式。
2.2.4 其他模式类型
DTD和XML模式都属于封闭模式语言。也就是说,它们禁止所有模式中没有明确允许的东西。XML模式语言提供了一些扩展性,但它基本上还是属于封闭语言。
其他一些模式语言是开放的,它们允许出现模式没有明确禁止的内容。这些语言可以用于替代DTD和XML模式,也可以作为它们的补充。对它们的处理是在对封闭语言处理后进行的。
如果需要构造一个约束规则,而它在DTD或XML模式中却是无法实现的,可能就需要使用另一种模式类型。例如,某税务系统可能会有如下规则:“如果性别值为男性,就不能存在产科费用这个元素。”应用程序中经常会存在这样的业务规则,另一种不同的模式类型可能更容易描述这样的约束。
这些可选的模式语言包括:
l Schematron:http://www.ascc.net/xml/resource/schematron/schematron.html;
l REgular LAnguage for XML Next Generation(RELAX NG):http://www.oasis-open.org/ committees/tc_home.php?wg_abbrev=relax-ng;
l XML-Data Reduced(XDR):http://www.ltg.ed.ac.uk/~ht/XMLData-Reduced.htm。
Schematron使用XSLT和XPath,因而可以将Schematron声明嵌入到XML模式文件内部以扩展它的应用范围。本章的“理解XSLT”和“XPath”部分将会对XSLT和XPath做更多的介绍。
目前使用的XML词汇还有很多种,下一节会介绍几种常用的词汇。