XML问题#7:W3C XML Schema 与文档类型定义(DTD) 比较

2002-8-19 15:07:20【作者】 畅享网 【进入论坛】
广告

XML问题#7:W3C XML Schema 与文档类型定义(DTD) 比较


David Mertz, Ph.D. (
mertz@gnosis.cx)

总裁,Gnosis Software, Inc.

2001 年 3 月

许多开发者都期待着 XML 模式能够很快取代 DTD 用于指定 XML 文档类型。尽管 David Mertz 相信 XML 模式在开发者宝库中是一种无价工具,但他对该模式将替代 DTD 持怀疑态度。XML 问题专栏的这一部分逐步尝试对模式和 DTD 进行比较,并阐明在 XML 模式世界中发生的事件。

虽然 W3C XML Schema 在许多场合中胜过 DTD,但仍然还有一些 DTD 更胜一筹的领域。开发者要不断地进行艰难的选择(这在 XML 世界中是司空见惯的事)。让我们开始对其中一些选项进行区分。

目前形势

将 XML 用作数据表示格式的主要原因是有可能指定文档的结构化需求:确定究竟什么类型的内容和子元素可以出现在元素中的一些规则(以及以什么顺序和基数性等)。在传统 SGML 派系中,文档规则的表示曾经是 DTD -- W3C XML 1.0 建议书的正式规范确实明确提供了 DTD。不过,有一些 DTD 无法实现的相当常见的约束;DTD 的主要限制在于它们缺乏数据类型的表达(可以指定一个元素必须包含 PCDATA,但无法指定它必须包含例如 nonNegativeInteger)。 还有一个次要问题,即 DTD 无法简化子元素基数性的规范(可以简洁地指定“一个或多个”子元素,但即使可能,指定“七到十二之间”也会过分冗长,甚至完全曲解)。

为了对付 DTD 的各种限制,一些 XML 用户曾呼吁一些指定文档规则的替代方法。总是有可能从编程上检查 XML 文档中的条件,但从本质上说,往往更需要施加更严格的标准,即“一个不满足一组正式规则的文档就是 无效文档”。W3C XML Schema 是满足这些要求的一个主要答案(但不是这里唯一可供选择的模式)。Steven Holzner 在 XML 内幕中将 XML 模式归纳为具有以下特征,值得在这里重申:

随着时间的推移,许多人都向 W3C 抱怨 DTD 太复杂,并要求使用一些更简单的方法。W3C 听取并指定了一个委员会来解决这一问题,然后拿出了一个比以往任何 DTD 都复杂得多的解决方案 (p.199)。
Holzner 继续道 -- 几乎所有 XML 程序员都同意(包括我自己)-- 如果不考虑其复杂性,W3C XML Schema 还是提供了许多重要能力,并值得用于许多确认规则类。

至少有两个基本的和概念性的缺陷存在于所有“到处模式”的目标中。第一个问题是刚刚于 2000 年 12 月 15 日结束其复审阶段的 W3C XML Schema Candidate Recommendation,不包含任何实体;通过扩展,它可以包括参数实体。第二个问题是,尽管存在增强的表达方式,仍然有许多文档规则不能用 XML 模式表示(一些建议提议利用 XSLT 来增强确认表达,但也可能存在和使用其它方法)。换句话说,模式无法执行 DTD 长期以来能够执行的所有操作,而从另一方面来讲,模式也无法表达人们希望对文档施加的进一步规则的完整集合。从更实际的角度来说,用于 XML 模式的工具不如用于 DTD 的工具来得成熟(特别在确认方面,这是核心问题)。

XML 文档确认规则整体上仍处于混乱状态。不幸的是,我无法预言每件事的最终结果将会怎样。(有关何时使用 DTD 可能比较有意义的摘要,请参阅侧栏“何时使用 DTD。”)同时,让我们看看 DTD 和 XML 模式能够表达哪些内容的一些具体细节。

丰富的类型

W3C XML Schema 真正出色的地方是在表达属性值和元素内容的类型约束上。而这恰恰是 DTD 最薄弱的地方。除了提供非常丰富的一组内置 simpleType 以外,XML 模式还允许您使用类似规则表达式的语法派生出新的 simpleType。内置类型包括您在使用编程语言时遇到的: string、int、float、unsignedLong、 byte 等等;但它们还包括大多数编程语言生来不具备的一些类型:timeInstant(即日期/时间)、 recurringDate(年中的天)、uriReference、 language、nonNegativeInteger。

例如,使用 DTD 时,将有类似于清单 1 中的声明:

清单 1:DTD "item" 元素定义

<!ELEMENT item (prodName+,USPrice,shipDate?)
<!ATTLIST item partNum CDATA>
<!ELEMENT prodName (#PCDATA)>
<!ELEMENT USPrice (#PCDATA)>
<!ELEMENT shipDate (#PCDATA)>

使用 W3C XML Schema 时,声明可以更具体(对 W3C Schema 的最初规定稍有修改):

清单 2:XML 模式 "item" 元素定义

<xsd:element name="item">
 <xsd:complexType>
 <xsd:sequence>
 <xsd:element name="prodName" type="xsd:string" maxOccurs="5"/>
 <xsd:element name="USPrice" type="xsd:decimal"/>
 <xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
 </xsd:sequence>
 <xsd:attribute name="partNum" type="SKU"/>
 </xsd:complexType>
</xsd:element>

<!-- Stock Keeping Unit, a code for identifying products -->
<xsd:simpleType name="SKU">
 <xsd:restriction base="xsd:string">
 <xsd:pattern value="\d{3}-[A-Z]{2}"/>
 </xsd:restriction>
</xsd:simpleType>

从表面上看,这些元素定义中有两个显著特性。首先是模式本身是格式完整的 XML 实例,其标记使用 xsd 名称空间(实际上,DTD 也是这样,但它只有处理指令,而没有这样的内容);其次(根据第一点的结论)是模式远比 DTD 繁琐。

除了语义方面的准确性以外,还可以看到模式示例能够执行一些 DTD 不可能完成的操作。prodName 类型在定义之间基本上是相同的,但模式中的 USPrice 和 shipDate 规范分别是 decimal 和 date 类型。 作为文本文件,具有这些元素的 XML 实例在元素内部包含一些 ASCII(或 Unicode)字符;不过,具有模式意识的确认器可以在 decimal 和 date 元素内部要求更具体的字符格式(其它类型也是一样)。 更有趣的是属性 partNum,它属于派生的专门类型。类型 SKU 不是内置类型,而是跟在 "SKU" 声明中给定模式后的一系列字符(具体来说,它必须有三位:一个连线和两个大写字母,按这样的顺序)。也有可能将 SKU 用于元素类型;它在这种情况下定义属性只是一种巧合。

在元素定义的 DTD 版本中,所有这些有趣的(如果是专门的,也可能相当复杂)类型一定简单地称之为 PCDATA,至于字符数据是什么样没有更多说明(在属性情况中是 CDATA)。

在类型丰富的元素/属性值中,模式巧妙地从描述 XML 实例的语法渐变到描述其语义。语法分析纯化论者可能会就我的描述提出异议:“内置模式类型是从语法上定义的,因此构建在这些内置类型上的模式在形式上也是符合语法的。”但在实际情况中,当声明一个给定的元素必须是 date 时,您实际上希望的是让元素包含一个日期。当然,表达语义信息不是件坏事,但有人会争论说最好同样将它限制在应用程序级别,而不是格式声明。毕竟有一些语义特性 -- 即使是简单的特性 -- 避开了模式,但在应用程序中和模式所表达的内容一样重要。 例如,当然 "stock-keeping unit" 必须类似于 "999-AA";但可能您还提供在十三以内的小装置。integer 被 13 整除性不能使用 XML 模式表达(因此您仍然无法在这一级别上为 widgetquantity 提供所需的约束)。这里的重点是说,即使有模式(胜过 DTD)的额外能力,仍可能需要在应用程序级别上执行后确认来确定 XML 文档是否在功能上有效。

出现约束

除了强大的类型声明以外,XML 模式还在 DTD 声明子元素模式的基数性能力的基础上进行了改进。不过,DTD 用于表达每个出现约束(基数性)的方法比 XML 模式总是笨拙许多。

在 DTD 中,符号:?、* 和 + 分别指定“零或一”、“零或多个”、“一个或多个”,其中一个量化了基数性。即,除了问号有能力说:“有或没有”以外,DTD 语法中似乎没有可以限制给定模式出现次数的东西(无论是单一子标记还是嵌套的一系列)。因此如何表达上面模式示例中 1-5 个 prodName 的出现似乎是个问题。同样地,如果没有 XML 模式属性 minOccurs,我们似乎就无法表达让某个事物出现特定次数的需求(而非“至少一次”)。实际上,DTD 的最小量词虽然有时不是很讲究,但已经够好的了。下面是等价的约束:

清单 3:“七到十二”个甜面圈的 XML 模式语法

<xsd:element name="donutorder">
 <xsd:complexType>
 <xsd:sequence>
 <xsd:element name="donut" type="xsd:string"
 minOccurs="7" maxOccurs="12" />
 </xsd:sequence>
 </xsd:complexType>
</xsd:element>


<!ELEMENT donut (#PCDATA)>
<!ELEMENT donutorder
 (donut,donut,donut,donut,donut,donut,donut,
 donut?,donut?,donut?,donut?,donut?)

当然,如果获得大笔订单,DTD 看上去开始真的很糟糕!

枚举

无论是 DTD 还是 W3C XML Schema 都允许在属性中使用枚举类型,但模式是非常了不起的进步,因为它们还可以在元素内容中允许使用枚举类型。我认为,DTD 真正的缺点在于它缺乏这种能力。而且,模式的枚举方法非常全面而优秀。一个专门的 simpleType 可以包含一个枚举面。 这样的 simpleType 自动适合于属性或元素值类型。

让我们举例说明每种语法:

清单 4:用于枚举属性的 XML 模式语法

<xsd:simpleType name="shoe_color">
 <xsd:restriction base="xsd:string">
 <xsd:enumeration value="red"/>
 <xsd:enumeration value="green"/>
 <xsd:enumeration value="blue"/>
 <xsd:enumeration value="yellow"/>
 </xsd:restriction>
</xsd:simpleType>
<xsd:element name="person" type="person_type">
 <xsd:attribute name="shoes" type="shoe_color"/>
</xsd:element>

<!ATTLIST person shoes (red | green | blue | yellow)>

DTD 属性声明看来还算不错(可能在简明性方面更好),但如果您的模型在元素内容中放入 shoe_color,DTD 就变得很直截了当:

清单 5:用于枚举元素的 XML 模式语法

<xsd:element name="shoes" type="shoe_color">

目的

W3C XML Schema 可以让 XML 程序员表达一组新的对文档的声明性约束,而这是 DTD 做得不够的地方。对许多程序员来说,在模式中使用 XML 实例语法还会对 XML 任务的不同部分产生更大的不一致性(当然,其他人不同意这种说法)。模式的目标当然是随着它们为人们逐步了解,以及开发者增强更多用于它们的工具,而在重要性和作用域方面得到增长。

一种在模式工作开始时得到飞跃的方法是将从现有 DTD 到 XML 模式格式的转换自动化。很明显,自动转换无法对 XML 模式本身添加新的表达能力;但自动化可以创建好的模板,从中指定人们希望施加的特定类型约束。参考资料部分提供了到自动 DTD 至模式转换工具的两个链接。

参考资料

W3C Candidate Recommendation 24 October 2000 是 W3C XML Schema 的基本标准。

可以在 w3.org/TR/REC-xml 上找到 Extensible Markup Language (XML) 1.0 (Second Edition) W3C Recommendation 6 October 2000。 “第二版不是 XML 的新版本(第一次是在 1998 年 2 月 10 日发布的);它只不过合并了第一版勘误表所指示的更改。”

W3C 的 XML Schema 不是现有的唯一模式选项,这使得问题保持十分复杂的状态。RELAX(用于 XML 的规则表达式语言)现在是 ISO/IEC DIS (Draft International Standard) 22250-1。该标准在日本使用得最广泛,但它不特定于语言或文化。一个好的起点是 xml.gr.jp/relax/

The XML Schema Specification in Context 是有关 W3C XML Schema(与其它一些描述性格式相比)比较能力的很好的压缩摘要。

仔细查看 Yuichi Koike 的 Conversion Tool from DTDs to XML Schema。(它需要 Perl。)

Inside XML, Steven Holzner, New Riders, 2001 (ISBN 0-7357-1020-1) 是对几乎所有 XML 问题的详细的、信息性 -- 但可能有些散漫 -- 的有用的介绍。本专栏摘录了其中的精华和富幽默感的语句。

关于作者

David Mertz 曾渴望成为一名格言作者,他希望将对标准的重要意义在于有太多标准可供挑选这一观察创造成格言。但后来他又对 OS 的设计有了模糊认识。通过 mertz@gnosis.cx 与 David 联系,gnosis.cx/publish/ 上详细介绍了他的生活。非常欢迎对过去的、这一篇或将来的专栏文章提出意见和建议。

如果您希望与本文章的作者或其所在机构,进一步交流,请联系:畅享网 姜小姐
jill.jiang@amt.com.cn | 021-51096826-112 | 在线联系
企业信息化杂谈[原创]企业信息化的价值点探讨

我们都知道,信息技术是企业经营管理目标的手段之一。通俗点说,信息技术对企业而言就是一个工具。

IT管理—君无心[原创]文档信息安全简谈

文档信息安全工作要根据自身的需求来具体部署,也就是量体裁衣。信息安全等级划分、企业商业机密等是不同的概念。

第二届中国管理软件与IT服务年会—2..

“第二届中国管理软件与IT服务年会”于2008年7月23日-25日举行,由AMT集团与畅享网共同主办,无锡扬名高新技术产业园特别赞助支持。

CIO职场,强者生存?

在2008年,我们将继续看到CIO向商业运营方向发展。与此同时,我们也会看到商业管理人员将与技术管理人员一起竞争CIO岗位。 IT领导者的就职机会虽有不少,但其难度将会大幅提高。2……