在XML中引用外部DTD需用SYSTEM或PUBLIC关键字:SYSTEM用于本地/相对路径的私有DTD,如<!DOCTYPE book SYSTEM "book.dtd">;PUBLIC用于公共标准化DTD,含FPI和系统标识符,如XHTML声明;还可通过外部实体复用内容,但存在XXE安全风险,生产环境应禁用或谨慎配置,推荐改用更安全的XSD。

在XML中引用外部DTD,需在文档类型声明(DOCTYPE)中使用SYSTEM或PUBLIC关键字,并指定外部DTD的位置。这是实现结构校验和实体复用的关键机制。
使用 SYSTEM 引用本地或相对路径的DTD
SYSTEM用于引用私有、非标准化的外部DTD,通常指向本地文件系统或相对URL路径。
- 语法格式:
<!DOCTYPE root-element SYSTEM "dtd-file-path"> - 例如:
<!DOCTYPE book SYSTEM "book.dtd">(当前目录下的book.dtd) - 支持相对路径(
"dtd/book.dtd")和绝对路径("file:///home/user/book.dtd"),但不推荐硬编码绝对本地路径,影响可移植性
使用 PUBLIC 引用公共标准化DTD
PUBLIC用于引用已注册的公共DTD(如ISO标准、OASIS规范等),常配合公共标识符(FPI)与系统标识符(备用路径)使用。
- 语法格式:
<!DOCTYPE root-element PUBLIC "FPI" "system-id"> - 例如:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - FPI(公共标识符)是标准化字符串,不依赖网络;系统标识符是实际加载地址,解析器优先尝试FPI映射,失败时回退到该URL或本地缓存
在DTD中定义并引用外部实体
外部实体允许将重复内容(如版权信息、配置片段)抽离为独立文件,在XML中通过&entity-name;调用。
- 在外部DTD中声明:
<!ENTITY copyright SYSTEM "copyright.txt"> - 在XML文档内部DTD子集中也可声明:
<!DOCTYPE note [ <!ENTITY copyright SYSTEM "copyright.txt"> ]> - 在文档中使用:
©right;(注意:分号不可省略) - 注意:外部普通实体默认仅在解析时展开,且要求解析器启用外部实体解析(多数现代解析器出于安全默认禁用)
安全提醒与兼容性注意事项
外部DTD和外部实体存在XXE(XML External Entity)攻击风险,生产环境应谨慎处理。
- 主流解析器(如Java的DocumentBuilder、Python的xml.etree.ElementTree)默认禁用外部实体解析
- 若必须启用,需显式配置(如设置
feature http://apache.org/xml/features/disallow-doctype-decl为false,并启用http://xml.org/sax/features/external-general-entities) - 建议优先使用XML Schema(XSD)替代DTD,因其支持命名空间、数据类型,且外部引用更可控、更安全

















