3.2 引入DTD

使用DTD定义了合法的语义约束后,必须让XML文档引入该语义约束,以表明该XML文档遵守哪种语义约束。在XML文档中引入DTD主要有3种方式:

alt 内部DTD。

alt 外部DTD。

alt 公用DTD。

3.2.1 内部DTD

使用DTD最简单的方法是使用内部DTD,所谓内部DTD是指将DTD与XML数据定义放在同一份文档中,即将DTD定义在XML文档内部。内部DTD紧跟在XML声明和处理指令之后,以<!DOCTYPE开始,以]>结束。其语法格式如下:

alt

在内部DTD部分,可采用标准DTD语法详细定义XML文档的语义约束。看下面的例子:

程序清单:codes\03\3.2\innerDTD.xml

alt

DTD详细定义了XML文档中的合法元素、元素之间的顺序、元素的合法子元素和属性等语义约束。内部DTD完全能胜任该工作,但这意味着要为每份文档都定义一份DTD约束,因此相当烦琐:可能有一批文档都需要遵守相同的语义约束,则每份文档内都需要增加相同的DTD定义。这种情况下,采用外部DTD可能是更好的选择。

3.2.2 外部DTD

XML文档既可以将DTD包含在内部,也可以引用外部的DTD。

外部DTD的好处是:可以方便地被多个XML文档共享,只需定义一份DTD文档,即可为多个XML文档定义语义约束。在实际应用中,用于某种数据交换的XML文档,总是具有相同的语义要求,此时采用外部DTD就可以简化语义约束定义。这种简化还有更大的好处:当语义约束需要改变时,无须为每份文档分别改变DTD定义,而只需改变它们共享的外部DTD即可。

外部DTD的引用以<!DOCTYPE开始,以>结束,其声明格式如下:

alt

例如下面的代码:

alt

上面的URI是个绝对路径。除此之外,URI还可使用相对路径,例如下面所示语法也是完全正确的:

alt

通过外部DTD,可以方便地将DTD从XML文档中分离出来,单独形成一个DTD文件,从而实现语义约束和数据文件的分离。下面的两个文件是对上面使用内部DTD的XML文档的分离。DTD文件book.dtd的代码如下:

程序清单:codes\03\3.2\book.dtd

alt

在外部DTD文件中,仅定义了目标XML文档的语义约束。从上面的DTD文件中可以看出,外部DTD文件也可指定独立的XML声明,用于为DTD指定解码所用的字符集。


alt注意

为了让DTD能支持非西欧字符,应该为外部DTD文档指定声明,DTD声明和XML声明的语法完全相同。


下面是使用上述DTD的XML文档:

程序清单:codes\03\3.2\outerDTD.xml

alt

从上面的代码可以看出,该XML文档只定义了结构化数据,而不再包含语义约束的DTD信息。对于使用外部DTD的情形,可以非常方便地让多个XML文档共享同一个DTD语义约束。

3.2.3 公用DTD

有一种外部DTD,是由某个权威机构制定,供特定行业或公众使用,这种DTD又被称为公用DTD。公用DTD通过PUBLIC关键字引入,即使用PUBLIC替换原来使用SYSTEM的地方。如果将SYSTEM替换成PUBLIC,则意味着正在使用公用DTD,使用公用DTD时,还需给该DTD指定一个标识名。引用公用DTD的格式如下:

alt

公用DTD与外部DTD的区别在于:公用DTD使用PUBLIC代替了原来的SYSTEM,并增加了DTD标识名。关于公用DTD的实例,可以在web.xml等配置文件中找到,此处不再赘述。