☰
DTD 构建模块:从基础概念到实战应用
2026/10/23 2:59:44 网站建设 项目流程

1. 什么是 DTD

DTD(Document Type Definition,文档类型定义)是一种用于定义 XML 或 HTML 文档结构的规则集合。它规定了文档中可以出现哪些元素、元素的排列顺序、元素的属性以及元素之间的嵌套关系,是文档验证和结构化的重要基础。

简单来说,DTD 的作用包括:

  1. 定义文档中允许出现的元素和属性。
  2. 规定元素的嵌套顺序和出现次数。
  3. 为解析器提供验证依据,确保文档符合预期结构。
  4. 帮助不同系统之间共享和交换结构化数据。

DTD 既可以在文档内部声明,也可以作为外部文件被多个文档引用,是 XML 技术体系中最基础也最重要的组成部分之一。

2. DTD 的构建模块

DTD 的核心构建模块主要包括元素、属性、实体和 PCDATA 等。理解这些模块是掌握 DTD 的关键。

构建模块说明示例
元素文档中的基本结构单元,对应 XML 标签<title>、<author>、<book>
属性元素的附加信息,通过属性列表声明id、lang、type
实体用于定义可复用的文本片段或特殊字符&lt;、&copy;、自定义实体
PCDATA可解析字符数据,即元素内的文本内容书名、作者名等文本
CDATA字符数据,解析器不解析其中的内容代码片段、特殊格式文本

下面逐一深入介绍这些构建模块。

3. 元素声明

元素是 DTD 中最核心的构建模块。通过<!ELEMENT>声明,可以定义元素的名称和内容模型。

3.1 基本元素声明

<!ELEMENT book (title, author, price)> <!ELEMENT title (#PCDATA)> <!ELEMENT author (#PCDATA)> <!ELEMENT price (#PCDATA)>

上面的声明表示:book元素必须依次包含title、author和price三个子元素,而这三个子元素的内容都是可解析的文本(PCDATA)。

3.2 元素内容模型

DTD 支持多种内容模型,用于控制元素的嵌套规则。

<!-- 空元素:不包含任何内容 --> <!ELEMENT br EMPTY> <!-- 仅包含文本内容 --> <!ELEMENT name (#PCDATA)> <!-- 仅包含子元素,不包含文本 --> <!ELEMENT catalog (book+)> <!-- 包含文本和子元素的混合内容 --> <!ELEMENT description (#PCDATA | highlight)*> <!-- 任意内容 --> <!ELEMENT note ANY>

3.3 子元素出现次数

通过修饰符可以控制子元素出现的次数,这是 DTD 构建模块中非常实用的能力。

<!-- 逗号表示顺序:必须按顺序出现 --> <!ELEMENT book (title, author, price)> <!-- 竖线表示选择:只能出现其中一个 --> <!ELEMENT contact (phone | email)> <!-- 无修饰符:必须出现且只能出现一次 --> <!ELEMENT title (#PCDATA)> <!-- 问号:出现零次或一次 --> <!ELEMENT book (title, author?, price)> <!-- 星号:出现零次或多次 --> <!ELEMENT catalog (book*)> <!-- 加号:出现一次或多次 --> <!ELEMENT catalog (book+)>

下表总结了各种修饰符的含义:

修饰符含义示例
无必须出现且只能出现一次title
?出现零次或一次author?
*出现零次或多次book*
+出现一次或多次book+

4. 属性声明

属性用于为元素提供附加信息。在 DTD 中,通过<!ATTLIST>声明属性列表。

4.1 基本属性声明

<!ELEMENT book (title, author, price)> <!ATTLIST book id ID #REQUIRED lang CDATA "zh-CN" type (paper | ebook) "paper" >

上面的声明定义了book元素的三个属性:

  • id:类型为 ID,必须提供(#REQUIRED)。
  • lang:类型为 CDATA,默认值为 "zh-CN"。
  • type:枚举类型,可选值为 paper 或 ebook,默认值为 paper。

4.2 属性类型

DTD 支持多种属性类型,每种类型都有特定的用途。

<!ATTLIST book id ID #REQUIRED ref IDREF #IMPLIED refs IDREFS #IMPLIED title CDATA #IMPLIED lang NMTOKEN #IMPLIED langs NMTOKENS #IMPLIED type (paper | ebook) "paper" note ENTITY #IMPLIED notes ENTITIES #IMPLIED flag NOTATION #IMPLIED >

常用属性类型说明:

类型说明示例
CDATA字符数据,最常用的类型lang="zh-CN"
ID文档内唯一的标识符id="book-001"
IDREF引用文档中另一个元素的 IDref="book-001"
IDREFS多个 ID 引用,用空格分隔refs="book-001 book-002"
NMTOKEN名称标记,类似变量名lang="zh-CN"
NMTOKENS多个名称标记langs="zh-CN en-US"
枚举从给定列表中选一个值type="paper"

4.3 属性默认值

属性默认值决定了属性是否必须出现以及缺省时的处理方式。

<!ATTLIST book id ID #REQUIRED lang CDATA #IMPLIED type CDATA "paper" fixed CDATA #FIXED "v1.0" >
  • #REQUIRED:属性必须出现,否则文档无效。
  • #IMPLIED:属性可以省略,解析器不提供默认值。
  • 默认值:属性省略时使用指定的默认值。
  • #FIXED:属性值固定,文档中必须使用该值。

5. 实体声明

实体是 DTD 中用于定义可复用文本片段或特殊字符的构建模块。实体分为内部实体和外部实体。

5.1 内部实体

内部实体在 DTD 内部直接定义,使用<!ENTITY>声明。

<!ENTITY author "张三"> <!ENTITY company "示例科技有限公司"> <!ENTITY copyright "版权所有 &copy; 2026">

在 XML 文档中引用实体:

<book> <title>DTD 实战指南</title> <author>&author;</author> <publisher>&company;</publisher> <copyright>&copyright;</copyright> </book>

解析后,&author;会被替换为 "张三",&company;会被替换为 "示例科技有限公司"。

5.2 外部实体

外部实体引用外部文件中的内容,使用SYSTEM或PUBLIC关键字。

<!ENTITY logo SYSTEM "logo.png"> <!ENTITY footer SYSTEM "footer.xml"> <!ENTITY style PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

5.3 预定义实体

XML 提供了一些预定义实体,用于表示特殊字符,这些实体在 DTD 中可以直接使用。

实体字符说明
&lt;<小于号
&gt;>大于号
&amp;&和号
&quot;"双引号
&apos;'单引号

6. PCDATA 与 CDATA

PCDATA 和 CDATA 是 DTD 中两种重要的数据构建模块,理解它们的区别对正确设计 DTD 至关重要。

6.1 PCDATA

PCDATA(Parsed Character Data,可解析字符数据)是元素内会被解析器解析的文本内容。解析器会识别其中的实体引用和标记。

<!ELEMENT title (#PCDATA)>

在文档中使用:

<title>DTD &amp; XML 实战</title>

解析后,&amp;会被解析为&,最终文本为 "DTD & XML 实战"。

6.2 CDATA

CDATA(Character Data,字符数据)是解析器不解析的文本内容,常用于包含大量特殊字符的代码片段。

<!ELEMENT code (#PCDATA)>

在文档中使用 CDATA 段:

<code><![CDATA[ if (a < b && c > d) { console.log("条件成立"); } ]]></code>

CDATA 段中的<、>和&都会被原样保留,无需转义。

7. 完整 DTD 实例

下面通过一个完整的图书目录 DTD 实例,综合运用前面介绍的所有构建模块。

7.1 定义 DTD 文件

<!-- books.dtd --> <!ELEMENT catalog (book+)> <!ELEMENT book (title, author+, publisher?, price, description?)> <!ATTLIST book id ID #REQUIRED lang CDATA "zh-CN" type (paper | ebook) "paper" > <!ELEMENT title (#PCDATA)> <!ELEMENT author (#PCDATA)> <!ELEMENT publisher (#PCDATA)> <!ELEMENT price (#PCDATA)> <!ELEMENT description (#PCDATA | highlight)*> <!ELEMENT highlight (#PCDATA)> <!ATTLIST price currency CDATA "CNY" > <!ENTITY company "示例出版社"> <!ENTITY copyright "版权所有 &copy; 2026 &company;">

7.2 编写符合 DTD 的 XML 文档

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE catalog SYSTEM "books.dtd"> <catalog> <book id="book-001" lang="zh-CN" type="paper"> <title>DTD 构建模块实战</title> <author>张三</author> <author>李四</author> <publisher>&company;</publisher> <price currency="CNY">59.00</price> <description> 本书系统讲解 DTD 的 <highlight>元素、属性、实体</highlight> 等核心构建模块。 </description> </book> <book id="book-002" lang="en-US" type="ebook"> <title>XML Schema Essentials</title> <author>Jane Smith</author> <price currency="USD">29.99</price> </book> </catalog>

7.3 验证文档

可以使用支持 DTD 的解析器验证文档是否符合定义。下面是一个使用 Python 的验证示例:

import xml.etree.ElementTree as ET try: tree = ET.parse('catalog.xml') root = tree.getroot() print('XML 文档解析成功') for book in root.findall('book'): print(f"图书 ID: {book.get('id')}") title = book.find('title').text print(f"书名: {title}") except ET.ParseError as e: print(f'XML 解析失败: {e}')

运行结果:

XML 文档解析成功 图书 ID: book-001 书名: DTD 构建模块实战 图书 ID: book-002 书名: XML Schema Essentials

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询