在Java中剥离无效的XML字符

16 浏览
0 Comments

在Java中剥离无效的XML字符

我有一个XML文件,它是从数据库输出的。我正在使用Java SAX解析器解析XML并以不同的格式输出。XML包含一些无效字符,解析器会抛出类似“无效的Unicode字符(0x5)”的错误消息。

除了逐行预处理文件并替换这些字符外,是否有好的方法可以去除所有这些字符?到目前为止,我遇到了3个不同的无效字符(0x5、0x6和0x7)。这是一个大约4GB的数据库转储文件,我们将对其进行多次处理,因此每次获取新的转储文件时都需要等待额外的30分钟来运行预处理程序,这是一件很痛苦的事情,而且这不是我第一次遇到这个问题。

0
0 Comments

出现的原因:

在使用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字符串。

0
0 Comments

问题原因: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库解析。未来感谢你们。

0
0 Comments

问题出现的原因是在处理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数据的有效性和完整性。

0