你正写一个Java程序读取配置文件,突然弹出 org.xml.sax.SAXParseException;或者用Python的xml.etree.ElementTree加载XML时卡住,提示ParseError: not well-formed;又或者在网页里用JavaScript调DOMParser.parseFromString(),结果返回空文档……别急,XML解析报错其实就那几类典型问题,找准位置,改两行就能跑通。
1. XML本身格式不合法——先看是不是“缺胳膊少腿”
最常见的就是标签没闭合、引号不匹配、特殊字符没转义。比如把<user name="张&李">写成<user name="张&李">,&符号没转成&,解析器当场罢工。
解决方法:用浏览器直接打开XML文件(或复制内容粘贴到https://www.xmlvalidation.com这类在线校验工具),它会准确定位第几行第几个字符出错。本地开发时,VS Code装个“XML Tools”插件,保存时自动高亮语法错误。
2. 编码声明和实际编码对不上
文件开头写着<?xml version="1.0" encoding="UTF-8"?>,但实际保存成了GBK编码,解析器按UTF-8去读,中文部分就会乱码+报错。
检查方式:用记事本另存为,看右下角显示的是什么编码;或用Notepad++打开,右下角明确标出“UTF-8”“ANSI”等。统一改成UTF-8无BOM格式最稳妥。
3. DTD或XSD校验失败,但你根本不需要校验
有些XML开头带<!DOCTYPE ...>或引用了远程XSD,而你的网络不通、服务器挂了,或者DTD里定义了不允许的属性,解析器就会报错停住。
临时绕过方法(以Java为例):
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false); // 关闭验证
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);Python中用etree.XMLParser(no_network=True, resolve_entities=False)也能避免外网请求拖垮解析。
4. 命名空间搞混了,查不到节点
XML里写了<rss xmlns="http://purl.org/rss/1.0/">,但你用tree.find('item')死活找不到——因为默认命名空间没声明,所有元素实际都在那个URI下。
正确写法(Python示例):
namespaces = {'ns': 'http://purl.org/rss/1.0/'}
tree.find('ns:item', namespaces)Java或JavaScript同理,查节点前必须显式注册命名空间前缀。
5. 特殊字符出现在文本内容里,没用CDATA包住
比如XML中有<desc>价格<50元</desc>,这里的<50会被当成新标签开始,直接报错“unexpected token”。正确写法是:
<desc><![CDATA[价格<50元]]></desc>或者把<替换成<,&替换成&。
下次再遇到XML报错,先打开文件用浏览器或校验工具扫一眼,90%的问题藏在前五行。不是代码不行,是XML自己没站稳脚跟。