在Java中剥离无效的XML字符
出现的原因:
在使用Xalan的org.apache.xml.utils.XMLChar
类时,使用了XMLChar.isValid()
方法来判断字符是否为有效的XML字符。然而,该方法在处理代理字符时存在问题。代理字符由高位和低位两个字符组成,当分别判断这两个字符时,XMLChar.isValid()
方法会返回false,导致最终判断代理字符为无效。
解决方法:
为了解决这个问题,需要对代理字符进行特殊处理。可以使用下面的代码来修复这个问题:
public static String stripInvalidXmlCharacters(String input) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < input.length(); i++) { char c = input.charAt(i); if (Character.isHighSurrogate(c) && i + 1 < input.length()) { char low = input.charAt(i + 1); if (Character.isLowSurrogate(low) && XMLChar.isValid(Character.toCodePoint(c, low))) { sb.append(c); sb.append(low); } i++; } else if (XMLChar.isValid(c)) { sb.append(c); } } return sb.toString(); }
这段代码在判断字符为代理字符时,会检查其后是否存在低位字符,并且判断组合后的代理字符是否有效。如果有效,则将整个代理字符添加到结果中。如果不是代理字符或者代理字符无效,则将字符添加到结果中。
使用修复后的代码,可以正确地处理代理字符,将无效的XML字符过滤掉,得到有效的XML字符串。
问题原因:XML文件中包含了一些无效的字符。
解决方法:使用Atlassian开发的命令行XML清理工具。下载并安装atlassian-xml-cleaner-0.1.jar文件。在DOS控制台或shell中,定位到XML或ZIP备份文件所在的位置,并执行以下命令:java -jar atlassian-xml-cleaner-0.1.jar data.xml > data-clean.xml。这将删除data.xml中的无效字符,并将清理后的内容保存到data-clean.xml文件中。
补充信息:如果需要为市场构建一个附加组件,可以使用com.atlassian.core.util.xml.XMLCleaningReader类替换无效字符。
来自未来的留言(2020年):第二个链接对我有效,这个JAR文件解决了我遇到的数千个包含各种非法字符的XML文件的严重问题。通过运行这个工具,这些文件被标准化,并且可以被Python的lxml库解析。未来感谢你们。
问题出现的原因是在处理XML数据时,可能会遇到包含无效的XML字符的情况。无效的XML字符是指Unicode编码中的一些特殊字符,这些字符不能直接包含在XML文档中,因为它们可能会导致解析错误或破坏XML结构。解决方法是使用正则表达式来过滤掉这些无效的XML字符。
对于JDK6,可以使用以下正则表达式来匹配并删除无效的XML字符:
Pattern INVALID_XML_CHARS = Pattern.compile("[^\\u0009\\u000A\\u000D\\u0020-\\uD7FF\\uE000-\\uFFFD\uD800\uDC00-\uDBFF\uDFFF]"); ... INVALID_XML_CHARS.matcher(stringToCleanup).replaceAll("");
在JDK7中,可以使用\x{10000}-\x{10FFFF}
的表示方法来代替\uD800\uDC00-\uDBFF\uDFFF
,这样更简单易懂。
通过使用上述的正则表达式,可以将包含无效XML字符的字符串清理掉,从而确保XML数据的有效性和完整性。