XML解析出现An invalid XML character (Unicode: 0x**) was found in the comment.

本文介绍了一种解决从华为和中兴网管获取的XML文件中包含非法Unicode字符(如0x1e/0x1c)的问题的方法。通过过滤这些非法字符,可以确保XML文件能够被正确解析。
最近从华为和中兴网管上获取采集器返回值时,其产生的xml文件中老是出现0x1e/0x1c等字符,导致xml无法解析。

网上有较简单的方法就是,过滤掉其中的字符,具体做法是:

//添加此段代码,是为了临时解决中兴/华为创建tnp返回文件中出现0x1e/0x1c等xml无法识别的Unicode字符
            //过滤掉非法字符,以确保能解析out文件,by chaisson
            InputStream is  = null;
            StringBuffer xml = null;
            if(this.fileName.contains("createTrailNtwProtection")){
            	xml = new StringBuffer();
                String line = null;
                while((line = bufReader.readLine())!=null){
                	line = line.replaceAll("[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]", "");
                	xml.append(line);
                	logger.info(line);
                }
                is = new ByteArrayInputStream(xml.toString().trim().getBytes());
            }

参考自:http://sjsky.iteye.com/blog/1055063
<think>我们正在处理一个XML解析错误:文档元素内容中包含无效的Unicode字符(0x16)Unicode字符0x16是一个控制字符(属于C0控制字符),在XML 1.0规范中,除了制表符(0x09)、换行(0x0A)和回车(0x0D)之外,其他控制字符都是不允许直接出现在XML文档中的。在XML 1.1中,允许使用更多的控制字符,但需要以转义形式出现(例如使用字符实体引用或数字字符引用)。然而,0x16这个字符在XML 1.1中也是不允许直接出现的。 解决方案通常包括: 1. 在生成XML之前,清理数据,移除或替换无效字符。 2.解析XML时,使用解析器设置来忽略或替换这些字符(如果解析器支持)。 具体步骤: 方法一:在生成XML的源头清理数据 如果我们可以控制XML的生成过程,那么应该在数据写入XML之前过滤掉无效字符。例如,在Java中可以使用正则表达式移除无效字符: ```java String sanitized = original.replaceAll("[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]", ""); ``` 方法二:在解析时处理(如果解析器支持) 一些XML解析器提供了忽略或替换这些字符的选项。例如,在Java的SAX解析器中,可以设置属性: ```java SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); XMLReader reader = parser.getXMLReader(); reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); // 或者使用自定义的过滤器 ``` 但是,并非所有解析器都支持直接忽略这些字符。另一种方法是使用过滤器(FilterReader)在解析前过滤输入流。 方法三:预处理XML文件 如果我们无法修改生成过程,可以在解析前对XML文件进行预处理,移除无效字符。例如,使用命令行工具(如sed)或编写一个简单的脚本。 在Python中,我们可以这样预处理: ```python import re def remove_invalid_chars(xml_str): # 移除非法的XML 1.0字符(除了制表符、换行、回车) return re.sub(r'[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]', '', xml_str) with open('input.xml', 'r', encoding='utf-8') as f: content = f.read() clean_content = remove_invalid_chars(content) with open('clean.xml', 'w', encoding='utf-8') as f: f.write(clean_content) ``` 注意:0x16(即十进制的22)在正则表达式中可以用`\x16`表示。 方法四:使用字符实体引用 在XML中,我们可以用数字字符引用来表示控制字符,例如``。但是,XML规范不允许在元素内容中直接出现控制字符,所以这种方法并不合法。因此,唯一正确的方法是移除或替换这些字符(例如用空格或空字符串)。 根据问题中引用的错误信息(引用[1]和引用[2])并不直接相关,但我们可以参考错误处理的思想:确保消息格式正确(避免无效目标)和明确识别设备(避免歧义)。类比到XML解析,我们需要确保XML文档格式正确(移除无效字符)以避免解析错误。 因此,推荐的方法是预处理XML文件,移除无效的Unicode控制字符。 相关问题: 1. 如何检测XML文件中的无效字符? 2. 除了移除无效字符,还有其他处理方式吗? 3. 不同编程语言中如何实现XML无效字符的过滤? 4. XML 1.0XML 1.1在字符处理上有什么不同?</think>### 解决 XML 解析错误:无效 Unicode 字符 (0x16) XML 规范(XML 1.01.1)严格限制元素内容中允许的 Unicode 字符。字符 `0x16`(SYNCHRONOUS IDLE,十进制 22)属于 **C0 控制字符**(`0x00-0x1F`),在 XML 中是非法的(除制表符 `0x09`、换行 `0x0A` 和回车 `0x0D` 外)。以下是修复方法: --- #### 方法 1:预处理 XML 数据(推荐) 在解析前移除非法字符: ```python import re def clean_xml(xml_str): # 移除非法的 C0 控制字符(保留制表符、换行、回车) return re.sub(r'[\x00-\x08\x0B\x0C\x0E-\x1F]', '', xml_str) with open("input.xml", "r", encoding="utf-8") as f: dirty_xml = f.read() clean_xml = clean_xml(dirty_xml) # 解析 clean_xml ``` --- #### 方法 2:解析时过滤(依赖解析器) 部分 XML 库支持过滤非法字符: - **Java (SAX)**: ```java SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); parser.parse(input, handler); // 启用 FEATURE_SECURE_PROCESSING 的解析器会自动过滤 ``` - **Python (lxml)**: ```python from lxml import etree parser = etree.XMLParser(recover=True) # 尝试恢复模式 tree = etree.parse("input.xml", parser) ``` --- #### 方法 3:修改数据源 如果控制 XML 生成: 1. **替换非法字符**:将 `0x16` 转换为合法字符(如空格) 2. **编码转义**:使用 Unicode 转义序列 `\u0016`(需确保解析器支持) --- #### 错误原因分析 - `0x16` 通常来自二进制文件误存为文本、编码错误或通信协议残留[^1]。 - XML 规范明确定义合法字符范围(Char 生产规则),控制字符违反格式约束[^2]。 --- ### 相关问题 1. 如何批量检测 XML 文件中的非法 Unicode 字符? 2. 不同编程语言(Java/Python/C#)中哪些 XML 解析器支持自动过滤控制字符? 3. XML 1.0XML 1.1 在字符处理规则上有哪些关键区别? 4. 如何防止数据源生成包含控制字符的 XML? [^1]: The format of the specified message destination is invalid. [^^2]: The requested system device cannot be identified due to multiple indistinguishable devices potentially matching the identification criteria.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值