6.3 命名空间和DTD

由于DTD是一种比较早的XML语义约束方式,对命名空间的支持比较有限,在定义一份DTD时无法为其指定类似于targetNamespace的属性,因此可以认为由DTD定义的元素和属性都没有命名空间。

虽然DTD对命名空间没有很好的支持,但我们依然可以使用多个DTD里定义的元素和属性,如以下DTD里定义了几个元素:

程序清单:codes\06\6.3\book.dtd

alt

上面的DTD定义了几个与图书相关的元素,下面的DTD中则定义了几个与游戏相关的元素:

程序清单:codes\06\6.3\game.dtd

alt

如果需要在XML文档中同时使用这两份DTD中定义的元素,从XML文档有效性角度来看,这是不可能的,但可以通过如下方式来定义:

程序清单:codes\06\6.3\item-list.xml

alt

上面的XML文档虽然依然是无效的XML文档——因为XML文档无法一次引入2个DTD作为语义约束,但XML用户可以明白:所有以book前缀限定的元素都来自于book.dtd,而所有以game前缀限定的元素都来自于game.dtd。

如果开发者想让该XML文档既是有效的,又可以支持命名空间的概念,那只能在其内使用内部DTD,如下所示:

程序清单:codes\06\6.3\innerDTD.xml

alt

查看上面的XML文档中的DTD定义,我们不难发现:在这份XML文档的内部DTD中定义元素时,为所有元素都指定了限定短名。

这样定义DTD的实质是将形如book:name的字符串整体当成了元素名,这意味着如果希望改变某个元素的限定前缀,程序还必须相应地修改该XML里的内部DTD。这将非常麻烦,因此如果希望在XML文档中使用命名空间,应该首选Schema作为语义约束,而不是使用DTD作为语义约束。