XML是一种可扩展标记语言,主要用于存储和传输结构化数据,而DTD是XML规范中用于定义文档结构的配套工具,二者结合可以让XML文档的使用更规范、更可靠。

什么是DTD
DTD全称为Document Type Definition,也就是文档类型定义,它是一套语法规则,用来描述XML文档的合法结构。通过DTD,我们可以明确指定XML文档里能出现哪些元素,每个元素可以包含什么内容,元素有哪些属性,以及元素之间的嵌套顺序和层级关系。
DTD和XML的关系
DTD是XML文档的配套约束文件,二者是约束与被约束的关系。XML文档本身只要求格式基本正确,比如标签要闭合、嵌套要合理,但没有强制要求文档内容必须符合某个特定的结构。而DTD就是给XML文档加上结构约束,让XML文档必须按照DTD定义的规则来编写。
我们可以在XML文档内部直接嵌入DTD规则,也可以通过外部文件引入DTD。如果是内部DTD,会放在XML文档开头的<!DOCTYPE>声明中;如果是外部DTD,只需要通过<!DOCTYPE>指定外部DTD文件的路径即可。
DTD在XML中的作用
统一文档结构标准
当多个开发者或者多个系统需要交互XML格式的数据时,通过DTD可以统一XML文档的结构要求,避免出现不同人编写的XML文档结构差异过大,导致解析端无法正确处理的问题。
验证文档合法性
XML解析器在解析文档之前,可以先根据关联的DTD校验XML文档是否符合结构要求。如果文档不符合DTD定义的规则,比如出现了DTD未定义的元素,或者元素嵌套顺序错误,解析器会直接报错,避免解析到错误数据。
提升文档可读性
有了DTD的约束,XML文档的结构会更统一,其他开发者看到XML文档时,也可以通过对应的DTD快速了解文档的结构规则,降低理解成本。
DTD基本使用示例
下面是一个内部DTD结合XML的使用示例,DTD定义了学生信息文档的结构,要求根元素是students,里面可以包含多个student子元素,每个student有id属性,并且包含name、age、class三个子元素。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE students [
<!ELEMENT students (student+)>
<!ELEMENT student (name,age,class)>
<!ATTLIST student id CDATA #REQUIRED>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT class (#PCDATA)>
]>
<students>
<student id="1001">
<name>张三</name>
<age>18</age>
<class>高三一班</class>
</student>
<student id="1002">
<name>李四</name>
<age>17</age>
<class>高三二班</class>
</student>
</students>上面的示例中,<!DOCTYPE>内部就是DTD规则,定义了元素和属性的要求,后面的XML文档严格按照这个规则编写,就是合法的XML文档。如果我们在student里多加一个未定义的score元素,解析器校验时就会提示错误。
外部DTD的使用
如果DTD规则需要在多个XML文档中复用,就可以把DTD规则单独写到一个.dtd文件中,然后在XML文档中引入。比如我们把上面的DTD规则保存到student.dtd文件中:
<!ELEMENT students (student+)> <!ELEMENT student (name,age,class)> <!ATTLIST student id CDATA #REQUIRED> <!ELEMENT name (#PCDATA)> <!ELEMENT age (#PCDATA)> <!ELEMENT class (#PCDATA)>
然后在XML文档中通过如下方式引入:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE students SYSTEM "student.dtd">
<students>
<student id="1001">
<name>张三</name>
<age>18</age>
<class>高三一班</class>
</student>
</students>这里的SYSTEM表示引入的是本地外部DTD文件,如果是公共的DTD,还可以使用PUBLIC关键字指定DTD的公共标识符和文件路径。