DTD约束
DTD约束是早期出现的一种XML约束模式语言,根据它的语法创建的文件称为DTD文件。在一个DTD文件中,可以包含元素的定义、元素之间关系的定义、元素属性的定义以及实体和符号的定义。接下来通过一个案例来简单认识一下DTD约束,如例1、例2所示。
例1 book.xml
1 <?xml version="1.0" encoding="gb2312"?>
2 <书架>
3 <书>
4 <书名>Java就业培训教程</书名>
5 <作者>张孝祥</作者>
6 <售价>58.00元</售价>
7 </书>
8 <书>
9 <书名>EJB3.0入门经典</书名>
10 <作者>黎活明</作者>
11 <售价>39.00元</售价>
12 </书>
13 </书架>
例2 book.dtd
1 <!ELEMENT 书架 (书+)>
2 <!ELEMENT 书 (书名,作者,售价)>
3 <!ELEMENT 书名 (#PCDATA)>
4 <!ELEMENT 作者 (#PCDATA)>
5 <!ELEMENT 售价 (#PCDATA)>
例2所示的book.dtd是一个简单的DTD约束文档。在例1中,book.xml中定义的每个元素都是按照book.dtd文档所规定的约束进行编写的。接下来针对例1-7所示的约束文档进行详细地讲解,具体如下:
●在第1行中,使用<!ELEMENT …>语句定义了一个元素,其中“书架”是元素的名称,“(书+)”表示书架元素中有一个或者多个书元素,字符“+”用来表示它所修饰的成分必须出现一次或者多次。
●在第2行中,“书”是元素名称,“(书名,作者,售价)”表示元素书包含书名、作者、售价这三个子元素,并且这些子元素要按照顺序依次出现。
● 在第3~5行中,“书名”、“作者”和“售价”都是元素名称,“(#PCDATA)”表示元素中嵌套的内容是普通的文本字符串。
对DTD文件有了大致了解后,如果想使用DTD文件约束XML文档,必须在XML文档中引入DTD文件。在XML文档中引入外部DTD文件有两种方式,具体如下:
(1)<!DOCTYPE 根元素名称 SYSTEM "外部DTD文件的URI">
(2)<!DOCTYPE 根元素名称 PUBLIC "DTD名称" "外部DTD文件的URI">
在上述两种引入DTD文件的方式中,第一种方式用来引用本地的DTD文件,第二种方式用来引用公共的DTD文件,其中“外部DTD文件的URI”指的是DTD文件的存放位置,对于第一种方式,它可以是相对于xml文档的相对路径,也可以是一个绝对路径,而对于第二种方式,它是Internet网上的一个绝对URL地址。
接下来对例1进行修改,在XML文档中引入本地的DTD文件book.dtd,如例3所示。
例3 book.xml
1 <?xml version="1.0" encoding="gb2312"?>
2 <!DOCTYPE 书架 SYSTEM "book.dtd">
3 <书架>
4 <书>
5 <书名>Java就业培训教程</书名>
6 <作者>张孝祥</作者>
7 <售价>58.00元</售价>
8 </书>
9 <书>
1 <书名>EJB3.0入门经典</书名>
2 <作者>黎活明</作者>
3 <售价>39.00元</售价>
4 </书>
5 </书架>
在例3中,由于引入的是本地的DTD文件,因此,使用的是SYSTEM属性的DOCTYPE声明语句。另外,在XML文档的声明语句中,standalone属性不能设置为“yes”。
如果希望引入一个公共的DTD文件,则需要在DOCTYPE声明语句中使用PUBLIC属性,具体示例如下:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
其中"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"是DTD名称,它用于说明DTD符合的标准、所有者的名称以及对DTD描述的文件进行说明,虽然DTD名称看上去比较复杂,但这完全是由DTD文件发布者去考虑的事情,XML文件的编写者只要把DTD文件发布者事先定义好的DTD标识名称进行复制就可以了。
DTD对XML文档的约束,除了外部引入方式实现外,还可以采用内嵌的方式。在XML中直接嵌入DTD定义语句的完整语法格式如下所示:
<?xml version="1.0" encoding="gb2312" standalone="yes"?>
<!DOCTYPE 根元素名 [
DTD定义语句
……
]>
接下来对例3进行修改,在book.xml文档中直接嵌入book.dtd文件,修改后的代码如例4所示。
例4 book.xml
1 <?xml version="1.0" encoding="gb2312" standalone="yes"?>
2 <!DOCTYPE 书架 [
3 <!ELEMENT 书架 (书+)>
4 <!ELEMENT 书 (书名,作者,售价)>
5 <!ELEMENT 书名 (#PCDATA)>
6 <!ELEMENT 作者 (#PCDATA)>
7 <!ELEMENT 售价 (#PCDATA)>
8 ]>
9 <书架>
10 <书>
11 <书名>Java就业培训教程</书名>
12 <作者>张孝祥</作者>
13 <售价>58.00元</售价>
14 </书>
15 <书>
16 <书名>EJB3.0入门经典</书名>
17 <作者>黎活明</作者>
18 <售价>39.00元</售价>
19 </书>
20 </书架>
例4实现了在XML文档内部直接嵌入DTD语句。需要注意的是,由于一个DTD文件可能会被多个XML文件引用,因此,为了避免在每个XML文档都添加一段相同的DTD定义语句,通常都将其放在一个单独的DTD文档中定义,采用外部引用的方式对XML文档进行约束。这样,不仅便于管理和维护DTD定义,还可以使多个XML文档共享一个DTD文件。