乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • XML 基础语法

    • XML 概述
    • XML 文档结构
    • XML 元素
    • XML 属性
    • XML 语法规则
    • XML 命名空间
    • XML 注释与处理指令
  • DTD 与文档验证

    • DTD 概述
    • DTD 元素声明
    • DTD 属性声明
    • DTD 实体声明
    • DTD 元素与属性对比
    • DTD 完整示例
  • XML Schema 定义

    • XML Schema 概述
    • XSD 简单类型
    • XSD 复杂类型
    • XSD 命名空间与引用
  • XPath 节点定位

    • XPath 概述
    • XPath 路径表达式
    • XPath 谓词与函数
  • XSLT 转换

    • XSLT 概述
    • XSLT 模板与匹配
    • XSLT 控制结构
    • XSLT 输出控制
  • XML 解析技术

    • XML 解析概述
    • DOM 解析
    • SAX 解析
    • StAX 解析
    • XML 与 Java — JAXP
  • XML 在 Java 中的应用

    • Spring XML 配置
    • MyBatis XML 映射
    • pom.xml 与 Maven
    • web.xml 配置详解
  • 现代数据格式对比

    • XML 与 JSON 对比
    • XML 与 YAML 对比
  • XML 显示与浏览器集成

    • XML 在浏览器中的显示
    • XMLHttpRequest 与 AJAX
    • 服务器端 XML 处理
  • XML 进阶查询与链接

    • XQuery 查询语言
    • XLink 超链接
    • XML 验证工具使用
  • XML Web 服务(选读)

    • XML Web 服务概述
    • SOAP 协议详解
    • WSDL 服务描述
    • RSS 内容聚合
    • RDF 资源描述框架

DTD 实体声明

本章定位 :掌握 DTD 中三种实体的定义和使用——内部一般实体、外部实体、参数实体。理解实体引用机制如何实现文本复用和 DTD 模块化。

定义与作用

实体 (Entity)是 XML 中的"宏"——一个名字代表一段文本或外部资源。当 XML 解析器遇到 &name; 时,会用实体的定义内容替换它。

DTD 支持三种实体类型:

  1. 内部一般实体 :在 DTD 中定义的文本常量,XML 文档中用 &name; 引用
  2. 外部实体 :引用外部文件的内容
  3. 参数实体 :仅在 DTD 内部使用的实体,用于模块化 DTD 定义

实体引用的核心价值是 DRY(Don't Repeat Yourself)——多处用到的文本只定义一次。

核心原理:实体引用替换流程

图解释 :解析器在遇到 &entity; 时查 DTD 的实体表,找到定义后用替换文本继续解析。外部实体的替换文本可能来自另一个文件。

语法/结构要点

三种实体对比

类型声明语法引用语法使用范围
内部一般实体<!ENTITY name "value">&name;XML 文档中
外部实体<!ENTITY name SYSTEM "file">&name;XML 文档中
参数实体<!ENTITY % name "value">%name;仅在 DTD 内

5 个预定义实体(不需要声明)

字符实体引用
<&lt;
>&gt;
&&amp;
'&apos;
"&quot;

完整示例:大翔用实体管理公司信息

场景说明

飞翔科技的运维 大翔 要为公司的 50 个 XML 配置文件中统一写入公司信息。如果每个文件都硬编码公司名称和版权声明,一旦公司改名或版权更新需要修改 50 个文件。大翔决定用外部实体来解决。

操作前:信息硬编码在每个文件中

<?xml version="1.0" encoding="UTF-8"?>
<config>
  <company>广州飞翔科技有限公司</company>
  <copyright>Copyright 2026 飞翔科技. All rights reserved.</copyright>
  <contact>support@learnto.cn</contact>
  <app-settings>
    <version>3.2.1</version>
  </app-settings>
</config>

操作后:实体复用

common.ent (公共实体文件):

<!ENTITY company "广州飞翔科技有限公司">
<!ENTITY copyright "Copyright 2026 飞翔科技. All rights reserved.">
<!ENTITY contact "support@learnto.cn">

app-config.xml (配置文件):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE config [
  <!ENTITY % common SYSTEM "common.ent">
  %common;
]>
<config>
  <company>&company;</company>
  <copyright>&copyright;</copyright>
  <contact>&contact;</contact>
  <app-settings>
    <version>3.2.1</version>
  </app-settings>
</config>

操作结果

现在,50 个 XML 文件都引用同一个 common.ent。如果公司改名或版权更新,只需修改 common.ent 一个文件,重新解析所有 XML 即可生效。大翔的总操作时间从 2 小时缩短到 2 分钟。

易错场景

错误一:在实体值中使用 & 而不转义

<!-- ❌ -->
<!ENTITY corp "乐途 & 伙伴">

<!-- ✅ -->
<!ENTITY corp "乐途 &amp; 伙伴">

错误二:参数实体引用在 DTD 外部

<!ENTITY % common "value1 | value2">
%common;   <!-- ✅ 在 DTD 中引用 -->

<!-- 在 XML 文档中使用 %common; ❌ -->

参数实体只能在 DTD 声明中使用(包括内部子集和外部 DTD 文件),不能在 XML 文档内容中使用。

错误三:实体循环引用

<!-- ❌ 致命错误 -->
<!ENTITY a "&b;">
<!ENTITY b "&a;">

面试考点

考点参考答案要点
XML 中有哪些预定义实体?为什么需要它们?5 个:&lt; <、&gt; >、&amp; &、&apos; '、&quot; "。因为 XML 解析器把 < 和 & 视为特殊字符,直接用会破坏语法
一般实体和参数实体的区别?一般实体在 XML 文档中用 &name; 引用,参数实体用 %name; 引用且只能在 DTD 内部使用。参数实体常用于模块化 DTD
外部实体的安全风险?外部实体可能被利用进行 XXE 攻击(读取服务器文件、发起 SSRF 请求)。现代 XML 解析器默认禁用外部实体
上一页
DTD 属性声明
下一页
DTD 元素与属性对比