XML解析报“实体未定义”错误是因为解析器遇到未声明的命名实体(如©),而XML仅默认支持5个内置实体;需预处理转义、启用DTD解析或改用数字字符引用。

为什么 XML 解析会报“实体未定义”错误
这个错误本质是 XML 解析器遇到了一个以 & 开头、以 ; 结尾的字符引用(比如 、©),但该名称在当前文档中没有被声明为合法实体。XML 默认只认识 5 个内置实体:&、、>、"、',其余如 、® 都属于 HTML 实体,在纯 XML 中不合法,除非你显式声明。
常见触发场景和错误写法
以下情况最容易引发该错误:
- 把 HTML 片段直接当 XML 解析(例如从网页抓取的含
的表格内容) - 手动生成 XML 字符串时,误用了 HTML 实体(如写
©而非©或©) - 使用了 DTD 声明但路径错误或内容缺失,导致
等未生效 - 某些库(如 Python 的
xml.etree.ElementTree)默认不加载 DTD,即使 XML 文件里写了..>,实体也不会被识别
如何安全处理带 HTML 实体的 XML 输入
最稳妥的方式是预处理,把非法实体转成 Unicode 字符或数字字符引用:
- Python 可用
html.unescape()先解码再解析(注意:仅适用于可信输入) - Java 中可用
StringEscapeUtils.unescapeHtml4()(Apache Commons Text) - Node.js 可用
he.unescape()(he包) - 若必须保留 XML 解析流程,可改用支持 DTD 的解析器(如 Python 的
lxml.etree并启用resolve_entities=True),但要确保 DTD 可访问且不含远程实体风险
from lxml import etree parser = etree.XMLParser(resolve_entities=True, dtd_validation=False) tree = etree.fromstring(xml_bytes, parser)
替代方案:避免实体,改用数字字符引用
数字字符引用( 、©)始终被 XML 解析器支持,无需 DTD 声明。这是最兼容、最安全的写法:
- 用
替代 - 用
©或©替代© - 用
“替代“
很多编辑器或模板引擎支持自动转换,关键是在生成 XML 阶段就避开命名实体,而不是依赖解析时补救。
真正麻烦的不是报错本身,而是有些系统一边悄悄替换掉非法实体,一边不报错——这种静默行为会让数据语义丢失,比明确报错更难排查。










