PostgreSQL 13 导入XML文件时报无效XML文档错误如何解决?
报错核心原因
你遇到的2200M错误本质是xmlparse函数无法识别合法的XML结构,从报错详情可以直接定位问题:你传入解析的内容里,XML开头的<已经被转义为HTML实体<,引号也被转义为",解析器读取到的第一个字符是&而非预期的<,所以抛出「Start tag expected, '<' not found」错误。
触发这个问题的常见场景有3种:
- 导入的XML文件本身不是原始XML,是经过其他程序转义后的内容,比如从网页直接复制保存的XML源码,内容已经做了HTML实体编码
- XML文件带UTF-8 BOM头,开头的不可见BOM字符干扰了解析器对起始标签的识别
- 文件实际编码和函数里指定的UTF-8不匹配,读取内容时出现乱码,导致标签结构被破坏
排查步骤
- 直接用文本编辑器打开目标XML文件,检查第一行内容:
- 如果第一行显示为
<?xml version="1.0" encoding="utf-8"?>,说明文件本身内容已被转义,属于源文件问题 - 如果第一行是正常的
<?xml version="1.0" encoding="utf-8"?>,则继续排查读取环节的问题
- 如果第一行显示为
- 临时修改导入函数返回文本类型,确认读取到的原始内容是否正常:
create or replace function xml_import_test(filename text) returns text volatile language plpgsql as $f$ declare content bytea; loid oid; lfd integer; lsize integer; begin loid := lo_import(filename); lfd := lo_open(loid,262144); lsize := lo_lseek(lfd,0,2); perform lo_lseek(lfd,0,0); content := loread(lfd,lsize); perform lo_close(lfd); perform lo_unlink(loid); return convert_from(content,'UTF8'); end; $f$; -- 执行测试查看返回内容是否和文件实际内容一致 select xml_import_test('filepath/filename.xml');
解决方法
根据排查结果对应处理即可:
场景1:文件本身已做实体转义
- 优先选择重新获取原始未转义的XML文件再导入
- 无法获取原始文件的话,修改
xml_import函数的返回逻辑,先做实体解码再解析:
return xmlparse(document replace( replace( replace(convert_from(content,'UTF8'), '<', '<'), '"', '"'), '>', '>') );
场景2:文件带UTF-8 BOM头
- 用文本编辑器将文件另存为「无BOM的UTF-8」格式后重新导入
- 也可以直接在函数里移除开头的BOM字符:
return xmlparse(document ltrim(convert_from(content,'UTF8'), chr(65279)));
场景3:编码不匹配
确认XML文件的实际编码,将convert_from(content,'UTF8')中的编码参数替换为对应编码即可,比如GBK、LATIN1等。
内容的提问来源于stack exchange,提问作者Sergei Walankov
相关产品推荐
相关产品推荐

