下面给你一份系统、清晰、深入浅出、并包含示例的《XML DTD(文档类型定义)深入解析指南》。这是理解 XML 数据结构、验证机制、早期 Web 服务格式的关键内容。
📘 一、什么是 DTD?
DTD(Document Type Definition)文档类型定义用于:
- 描述一个 XML 文档允许出现哪些标签(元素)
- 标签出现的顺序
- 标签是否可以嵌套
- 文本、属性等的数据类型
- 是否可出现多次、是否可选
一句话总结:
DTD 是 XML 的“语法规则书”
XML 写的合不合法,DTD 说了算。
📘 二、DTD 的 3 种声明方式
✔ 1. 内部 DTD(写在 XML 文件头部)
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Tom</to>
<from>Jim</from>
<heading>Hello</heading>
<body>Welcome</body>
</note>
✔ 2. 外部 DTD(独立 .dtd 文件)
XML:
<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
...
</note>
外部 DTD 文件 note.dtd:
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
...
✔ 3. 公共(PUBLIC)DTD:用于互联网共享标准
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
📘 三、DTD 中的核心声明语法
1. ELEMENT 元素定义(最核心)
格式:
<!ELEMENT 元素名 内容模型>
内容模型类型:
| 类型 | 说明 | 示例 |
|---|---|---|
EMPTY | 空元素,不含内容 | <br/> |
ANY | 任意内容(不推荐) | |
#PCDATA | 文本内容 | <title>xxx</title> |
| 子元素组合 | 定义嵌套结构 | (title, body) |
✔ 常用符号:
| 符号 | 说明 |
|---|---|
, | 顺序必须固定 |
| ` | ` |
? | 可选 0 或 1 次 |
* | 0 次或多次 |
+ | 1 次或多次 |
例子:
<!ELEMENT Book (Title, Author+, Price?)>
含义:
- Book 元素必须按顺序包含 Title → Author(至少 1 次)→ Price(可有可无)
2. ATTLIST 属性定义
格式:
<!ATTLIST 元素名 属性名 属性类型 默认值>
属性类型包括:
| 类型 | 说明 |
|---|---|
| CDATA | 文本字符串 |
| ID | 唯一标识(全 XML 中唯一) |
| IDREF | 引用某个 ID |
| IDREFS | 多个 ID |
| NMTOKEN | 由字母、数字、连字符组成 |
| ENUMERATION | 枚举类型 |
默认值类型:
| 类型 | 说明 |
|---|---|
| #REQUIRED | 必须出现 |
| #IMPLIED | 可选 |
| #FIXED | 固定值 |
| 字面值 | 默认值 |
例子:
<!ATTLIST Book id ID #REQUIRED>
<!ATTLIST Book category (History|Science|Novel) "Novel">
3. ENTITY 实体定义(类似变量或宏)
内部实体(文本替换)
<!ENTITY writer "阿杰">
使用:
<Author>&writer;</Author>
外部实体(引用外部文件)
<!ENTITY info SYSTEM "info.txt">
4. NOTATION(表示非 XML 数据格式)
例如图片类型:
<!NOTATION jpeg SYSTEM "image/jpeg">
📘 四、DTD 验证 XML 的原理
流程:
- XML 开头声明使用某个 DTD
- XML 解析器读取 DTD
- 使用 DTD 中的规则匹配 XML 结构
- 若标签顺序、数量、结构不正确 → 报错
📘 五、DTD 的典型示例(完整)
XML:
<?xml version="1.0"?>
<!DOCTYPE bookstore SYSTEM "bookstore.dtd">
<bookstore>
<book id="b1" category="Science">
<title>宇宙简史</title>
<author>Stephen Hawking</author>
<price>68</price>
</book>
</bookstore>
bookstore.dtd:
<!ELEMENT bookstore (book+)>
<!ELEMENT book (title, author+, price)>
<!ATTLIST book
id ID #REQUIRED
category (Science|History|Novel) "Novel">
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT price (#PCDATA)>
📘 六、DTD 的优点与缺点
✔ 优点:
- 简单、轻量
- 易读易写
- XML 标准早期广泛使用
- HTML/XHTML 都使用 DTD
✔ 缺点(为什么后期被 XSD 取代):
| 问题 | 说明 |
|---|---|
| 无法定义数据类型 | 例如 int、date、decimal |
| 扩展性差 | 不支持命名空间 |
| 无法表达复杂结构 | 例如继承、泛型 |
| 基于纯文本 | 校验能力弱 |
因此现代开发更推荐使用 XSD,但 DTD 是理解 XML 规则体系的基础。
📘 七、实际工程中 DTD 的主要用途
| 用途 | 说明 |
|---|---|
| 配置文件的结构校验(早期 Java 配置) | web.xml、struts.xml 老版本 |
| XHTML 网页验证 | W3C 验证工具 |
| 构建 XML 格式说明文档 | 用于简单 XML 格式 |
| SOAP / WebService 旧系统 | 常见于早期接口规范 |
📘 八、学习 DTD 后应该继续学习什么?
建议顺序:
- 理解 DTD(结构规则基础)
- 学习 XML Schema XSD(更强大的类型系统)
- 使用 XSD + DOM/SAX 做 XML 校验
- 了解 XPath 查询 XML