如何处理XML文件中的特殊字符和实体引用

3次阅读

xml解析遇&、

如何处理XML文件中的特殊字符和实体引用

XML解析时遇到&等实体报错怎么办

直接用原生解析器(如Python的xml.etree.ElementTree或JavaScript的DOMParser)加载含未声明或非法实体的XML,会抛出ParseErrorSyntaxError。这不是编码问题,而是XML规范强制要求:所有&必须成对出现为合法实体(如&"),不能孤立存在。

  • 最常见诱因是HTML片段混入XML内容(比如© 2024没转义成©
  • 手动拼接XML字符串时漏掉&转义,例如写成"price=19&tax=2"而非"price=19&tax=2"
  • 某些老旧系统导出的XML仍使用'但未在文档头部声明DOCTYPE

Python中用xml.etree.ElementTree安全加载含脏数据的XML

标准ET.parse()不接受自定义实体映射,遇到未知实体直接失败。绕过方法是预处理文本——把孤立&和常见HTML实体兜底转义,再交给解析器。

import re import xml.etree.ElementTree as ET 

def safe_parse_xml(xml_str):

将孤立 & 替换为 &(但保留已合法的 & < 等)

xml_str = re.sub(r'&(?!(amp|lt|gt|quot|apos);)', r'&', xml_str) # 补全常见HTML实体(如 &copy; → ©) xml_str = re.sub(r'&([a-zA-Z][a-zA-Z0-9]*);', r'&1;', xml_str) return ET.fromstring(xml_str)

示例:原始字符串含非法 & 和 ©

raw = '© 2024 & price=10&unit=kg' root = safe_parse_xml(raw) print(root.text) # 输出:© 2024 & price=10&unit=kg

JavaScript里用DOMParser处理含实体的XML字符串

DOMParser对实体更严格,连'都可能报错(除非文档类型声明支持)。安全做法是先用textContent提取原始字符,或改用非验证模式解析。

  • 不要依赖innerHTMLouterHTML反解XML——它们会二次转义
  • 若XML来自不可信源,优先用new DOMParser().parseFromString(xmlStr, 'application/xml'),检查parsererror元素是否存在
  • 真正需要保留'时,在XML顶部显式声明: ]>

生成XML时如何避免特殊字符引发问题

核心原则:永远不手动拼接XML字符串。所有内容必须经由序列化接口自动转义。

  • Python用ET.SubElement() + text属性赋值,ET.tostring()会自动处理zuojiankuohaophpcn
  • JavaScript用document.createElement()textContent(不是innerHTML
  • 若必须手写,只对&>"'做转义,其他Unicode字符(如中文、emoji)可直接保留

容易被忽略的一点:XML声明中的encoding必须与实际字节编码一致,否则即使实体正确,解析器也可能因字节错位误判&位置。

text=ZqhQzanResources