下面给你一份深入解析 XML 中字符实体与字符数据的学习指南,涵盖概念、分类、用法、示例和注意事项,帮助你系统理解 XML 的文本处理机制。


📘 一、什么是字符实体与字符数据?

在 XML 中,**字符实体(Character Entity)字符数据(Character Data)**是处理文本内容的两种核心机制。

  • 字符数据(Character Data, CDATA):XML 中实际的文本内容,包括字母、数字、符号等。
  • 字符实体(Entity):XML 为了避免保留字符冲突或便于复用文本而定义的“符号替换”。

简单理解:

CDATA 是原始文本,字符实体是“文本的别名或转义形式”。


📘 二、XML 中的字符实体分类


1️⃣ 预定义实体(最常用)

XML 定义了 5 个预定义实体,用于表示保留字符:

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

示例:

&lt;note>
    &lt;text>Tom &amp;amp; Jerry are friends &amp;lt;not enemies&amp;gt;&lt;/text>
&lt;/note>

解析后得到文本:

Tom &amp; Jerry are friends &lt;not enemies>


2️⃣ 数字字符实体(Unicode/ASCII 编码)

可使用 十进制十六进制表示任意 Unicode 字符。

  • 十进制:
&amp;#65;   &lt;!-- A -->
&amp;#20013; &lt;!-- 中文“中” -->

  • 十六进制(以 x 开头):
&amp;#x41;   &lt;!-- A -->
&amp;#x4E2D; &lt;!-- 中文“中” -->

数字实体可避免编码问题,尤其在跨平台、跨语言场景。


3️⃣ 自定义实体(用于复用文本)

可以在 DTD 或 XML 内部声明实体:

&lt;!ENTITY writer "阿杰">

使用:

&lt;author>&amp;writer;&lt;/author>

解析后得到:

阿杰

外部实体:

&lt;!ENTITY copyright SYSTEM "copyright.txt">

在文档中用 &copyright; 引入外部文件内容。


📘 三、CDATA 区块(Character Data 区块)


CDATA 是另一种处理文本的方式,用于保留原始文本,不解析实体和标签

语法:

&lt;![CDATA[ 文本内容 ]]>

示例:

&lt;content>&lt;![CDATA[
&lt;div>Tom &amp; Jerry&lt;/div>
]]>&lt;/content>

解析器输出:

&lt;div>Tom &amp; Jerry&lt;/div>

CDATA 内的 <>& 不会被解析为 XML 标签或实体。


📘 四、字符实体与 CDATA 的区别与适用场景

特性字符实体CDATA
是否需要转义
能否包含 XML 标签不可
是否可复用可(实体声明)不可
使用场景简单转义、跨平台文本富文本、HTML/脚本片段

📘 五、解析器对实体和 CDATA 的处理

  1. DOM 解析器
  • 实体会被解析为对应字符
  • CDATA 会被解析为 CDATASection 节点,可通过 .data.nodeValue 获取内容
  1. SAX 解析器
  • 实体会触发 characters() 事件
  • CDATA 会触发 startCDATA() / endCDATA()characters() 事件
  1. XSLT 处理
  • 默认会解析实体
  • 可以使用 <xsl:text disable-output-escaping="yes"> 保留特殊字符

📘 六、字符实体常见问题与注意事项


❌ 问题 1:实体未定义报错

  • XML 解析器要求所有自定义实体必须在 DTD 中定义
  • 预定义实体可直接使用

❌ 问题 2:数字实体编码不正确

  • 确保与 XML 声明编码一致(如 UTF-8)
  • 避免出现非法 Unicode 范围

❌ 问题 3:CDATA 中包含 ]]> 会导致解析错误

  • 解决方法:拆分 CDATA
&lt;![CDATA[...]]]]>&lt;![CDATA[>...]]>

❌ 问题 4:混合使用实体和 CDATA

  • CDATA 内不会解析实体
  • 如果希望解析实体,不要放入 CDATA

📘 七、字符实体与编码的关系

  • 实体解决了 XML 保留字符问题
  • 数字实体解决了不同编码环境下的字符问题
  • 使用 UTF-8 + 实体 + CDATA 结合,可实现跨语言、跨平台的安全 XML 文本传输

📘 八、总结与实践建议

  1. 小型文本:使用预定义实体或数字实体即可
  2. 富文本 / HTML / 脚本:使用 CDATA 区块
  3. 可复用文本:使用自定义实体
  4. 数字实体:避免编码不一致问题
  5. 混合场景:注意 CDATA 内实体不会被解析
  6. 解析器处理:DOM 会生成 CDATASection,SAX 需要事件处理
  7. 避免常见坑:CDATA 内不要出现 ]]>,自定义实体必须定义