1. 什么是 DTD 实体DTDDocument Type Definition文档类型定义实体是 XML 中用于定义可复用内容片段的一种机制。实体可以理解为一种宏或占位符通过预先定义一段内容在文档中引用时会被替换为实际的内容。合理使用实体可以显著减少重复代码提高文档的可维护性。DTD 实体主要分为两大类内部实体和外部实体。内部实体在 DTD 内部直接定义内容而外部实体则引用外部文件或资源。此外还有参数实体它专门用于 DTD 内部帮助构建更灵活的 DTD 结构。2. 实体的基本语法在 DTD 中实体通过!ENTITY声明来定义。其基本语法如下!ENTITY 实体名称 实体内容在 XML 文档中通过实体名称;来引用已定义的实体。下面是一个最简单的内部实体示例?xml version1.0 encodingUTF-8? !DOCTYPE 公司 [ !ENTITY 公司名 北京某某科技有限公司 !ENTITY 地址 北京市海淀区中关村大街 1 号 ] 公司 名称公司名;/名称 地址地址;/地址 /公司当 XML 解析器处理上述文档时公司名;会被替换为北京某某科技有限公司地址;会被替换为北京市海淀区中关村大街 1 号。这样当公司信息需要变更时只需修改 DTD 中的实体定义而不必逐一修改文档中的每个引用位置。3. 内部实体内部实体是最常用的实体类型其内容直接写在 DTD 声明中。内部实体可以包含文本、特殊字符的转义形式甚至可以引用其他实体。3.1 基本文本实体?xml version1.0 encodingUTF-8? !DOCTYPE 产品 [ !ENTITY 产品名 智能手表 Pro !ENTITY 版本 v2.0 !ENTITY 价格 ¥1999 ] 产品 名称产品名;/名称 版本号版本;/版本号 售价价格;/售价 /产品3.2 包含特殊字符的实体当实体内容包含 XML 特殊字符如、、时必须使用对应的实体引用进行转义?xml version1.0 encodingUTF-8? !DOCTYPE 说明 [ !ENTITY 警告 使用前请阅读 lt;说明书gt;并确保 lt;电源gt; 已连接 ] 说明 内容警告;/内容 /说明解析后警告;会被替换为使用前请阅读 说明书并确保 电源 已连接。3.3 实体嵌套引用实体可以引用其他已定义的实体形成嵌套关系?xml version1.0 encodingUTF-8? !DOCTYPE 公司信息 [ !ENTITY 公司名 某某集团 !ENTITY 子公司 某某科技子公司 !ENTITY 完整名称 公司名;旗下子公司; ] 公司信息 名称完整名称;/名称 /公司信息解析后完整名称;会被替换为某某集团旗下某某科技子公司。需要注意的是实体引用不能形成循环依赖否则会导致解析错误。4. 外部实体外部实体通过SYSTEM关键字引用外部文件或资源。外部实体又分为外部文本实体和外部二进制实体。4.1 外部文本实体?xml version1.0 encodingUTF-8? !DOCTYPE 报告 [ !ENTITY 引言 SYSTEM intro.txt !ENTITY 结论 SYSTEM conclusion.txt ] 报告 前言引言;/前言 总结结论;/总结 /报告在上述示例中intro.txt和conclusion.txt是外部文本文件解析器会读取这些文件的内容并替换到对应的实体引用位置。4.2 外部二进制实体外部二进制实体用于引用非文本资源如图片、音频等。二进制实体不能直接在 XML 内容中引用通常用于 DTD 属性声明中?xml version1.0 encodingUTF-8? !DOCTYPE 产品 [ !ENTITY 产品图片 SYSTEM product.jpg NDATA JPEG !NOTATION JPEG SYSTEM image/jpeg !ELEMENT 产品 EMPTY !ATTLIST 产品 图片 ENTITY #REQUIRED ] 产品 图片产品图片/这里通过NDATA关键字指定了二进制数据的类型并使用!NOTATION声明了对应的 MIME 类型。5. 参数实体参数实体是 DTD 内部使用的实体用于提高 DTD 的可复用性和可维护性。参数实体的定义和引用都发生在 DTD 内部使用%符号进行标识。5.1 参数实体的定义与引用?xml version1.0 encodingUTF-8? !DOCTYPE 图书 [ !ENTITY % 通用属性 作者 CDATA #IMPLIED 出版社 CDATA #IMPLIED !ELEMENT 图书 (书名, 简介) !ATTLIST 图书 %通用属性; !ELEMENT 书名 (#PCDATA) !ELEMENT 简介 (#PCDATA) ] 图书 作者张三 出版社清华大学出版社 书名XML 实战指南/书名 简介本书系统讲解 XML 核心技术。/简介 /图书在上述示例中参数实体%通用属性;在!ATTLIST声明中被展开为作者 CDATA #IMPLIED 出版社 CDATA #IMPLIED。5.2 参数实体复用 DTD 片段?xml version1.0 encodingUTF-8? !DOCTYPE 订单 [ !ENTITY % 地址元素 !ELEMENT 地址 (街道, 城市, 邮编) %地址元素; !ELEMENT 街道 (#PCDATA) !ELEMENT 城市 (#PCDATA) !ELEMENT 邮编 (#PCDATA) !ELEMENT 订单 (收货地址, 发货地址) !ELEMENT 收货地址 (地址) !ELEMENT 发货地址 (地址) ] 订单 收货地址 地址 街道中关村大街 1 号/街道 城市北京/城市 邮编100080/邮编 /地址 /收货地址 发货地址 地址 街道科技园路 88 号/街道 城市上海/城市 邮编200233/邮编 /地址 /发货地址 /订单通过参数实体可以将重复的 DTD 片段抽取出来实现一次定义、多处复用大大简化 DTD 的编写和维护。6. 预定义实体XML 规范预定义了五个实体用于表示 XML 语法中的特殊字符。这些实体无需在 DTD 中声明即可直接使用实体引用字符含义lt;小于号gt;大于号amp;和号apos;单引号quot;双引号例如要在 XML 内容中显示a b必须写成pa lt; b/p7. 实体在 DTD 中的实际应用场景7.1 统一管理版权信息?xml version1.0 encodingUTF-8? !DOCTYPE 文章 [ !ENTITY 版权 版权所有 © 2026 某某技术社区 !ENTITY 作者 李四 !ELEMENT 文章 (标题, 作者, 正文, 版权声明) !ELEMENT 标题 (#PCDATA) !ELEMENT 作者 (#PCDATA) !ELEMENT 正文 (#PCDATA) !ELEMENT 版权声明 (#PCDATA) ] 文章 标题DTD 实体入门/标题 作者作者;/作者 正文本文介绍 DTD 实体的基本概念与用法。/正文 版权声明版权;/版权声明 /文章7.2 构建可配置的 XML 配置模板?xml version1.0 encodingUTF-8? !DOCTYPE 系统配置 [ !ENTITY 数据库地址 jdbc:mysql://localhost:3306/app_db !ENTITY 数据库用户 root !ENTITY 数据库密码 123456 !ENTITY 缓存大小 256 !ELEMENT 系统配置 (数据库, 缓存) !ELEMENT 数据库 (地址, 用户, 密码) !ELEMENT 地址 (#PCDATA) !ELEMENT 用户 (#PCDATA) !ELEMENT 密码 (#PCDATA) !ELEMENT 缓存 (大小) !ELEMENT 大小 (#PCDATA) ] 系统配置 数据库 地址数据库地址;/地址 用户数据库用户;/用户 密码数据库密码;/密码 /数据库 缓存 大小缓存大小;/大小 /缓存 /系统配置8. 实体使用注意事项与安全风险在使用 DTD 实体时需要注意以下几点实体名称区分大小写实体名称是大小写敏感的Company;和company;是两个不同的实体。避免循环引用实体之间不能形成循环引用否则解析器会报错。外部实体安全风险外部实体可能被恶意利用导致 XXEXML 外部实体注入攻击。攻击者可以通过构造恶意的外部实体引用读取服务器上的敏感文件或发起 SSRF 请求。在解析不可信的 XML 时应禁用外部实体解析。实体内容中的特殊字符实体内容中的、、等字符必须使用对应的实体引用进行转义。参数实体仅在 DTD 中使用参数实体不能出现在 XML 文档内容中只能在 DTD 内部使用。下面是一个存在 XXE 风险的示例实际开发中应避免直接解析此类文档?xml version1.0 encodingUTF-8? !DOCTYPE 恶意 [ !ENTITY xxe SYSTEM file:///etc/passwd ] 恶意xxe;/恶意在 Java 中使用 DocumentBuilderFactory 解析 XML 时建议通过以下方式禁用外部实体import javax.xml.parsers.DocumentBuilderFactory; public class SecureXmlParser { public static DocumentBuilderFactory createSecureFactory() { DocumentBuilderFactory factory DocumentBuilderFactory.newInstance(); try { factory.setFeature(http://apache.org/xml/features/disallow-doctype-decl, true); factory.setFeature(http://xml.org/sax/features/external-general-entities, false); factory.setFeature(http://xml.org/sax/features/external-parameter-entities, false); } catch (Exception e) { throw new RuntimeException(无法配置安全的 XML 解析器, e); } return factory; } }9. 总结DTD 实体是 XML 文档中非常实用的功能它允许开发者定义可复用的内容片段从而减少重复、提高可维护性。本文从内部实体、外部实体、参数实体、预定义实体四个维度进行了系统讲解并通过丰富的代码示例展示了实体的定义、引用和实际应用场景。在实际开发中合理使用实体可以让 XML 文档更加简洁和灵活但同时也要警惕外部实体带来的安全风险确保在解析不可信 XML 时采取必要的防护措施。