在Java中剥离无效的XML字符

时间:2008-09-18 15:36:56

标签: java xml

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

等错误

除了预先处理文件并替换它们之外,有没有一种方法可以删除所有这些字符?到目前为止,我遇到了3个不同的无效字符(0x5,0x6和0x7)。这是一个~4gb的数据库转储,我们将要处理它多次,所以每次我们得到一个新的转储来运行一个预处理器时,不得不再等30分钟,这将是一个痛苦,这不是我第一次遇到这个问题。

6 个答案:

答案 0 :(得分:21)

我使用了Xalan org.apache.xml.utils.XMLChar类:

public static String stripInvalidXmlCharacters(String input) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < input.length(); i++) {
        char c = input.charAt(i);
        if (XMLChar.isValid(c)) {
            sb.append(c);
        }
    }

    return sb.toString();
}

答案 1 :(得分:9)

我没有亲自使用过这个,但是Atlassian制作了一个可以满足您需求的命令行XML清理程序(它主要是为了JIRA,但XML是XML):

  

下载atlassian-xml-cleaner-0.1.jar

     

打开DOS控制台或shell,找到计算机上的XML或ZIP备份文件,此处假设称为data.xml

     

执行命令    java -jar atlassian-xml-cleaner-0.1.jar data.xml&gt;数据clean.xml

     

这会将data.xml的副本写入data-clean.xml,并删除无效字符。

答案 2 :(得分:6)

我使用下面的正则表达式似乎与JDK6的预期一致:

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}作为BMP之外的最后一个范围而不是\uD800\uDC00-\uDBFF\uDFFF符号,这些符号并不那么容易理解。

答案 3 :(得分:3)

在将澳大利亚出口关税的内容解析为XML文档时,我遇到了类似的问题。我无法使用此处建议的解决方案,例如: - 使用从命令行调用的外部工具(jar)。 - 请澳大利亚海关清理源文件。

目前解决此问题的唯一方法是逐个字符地遍历源文件的整个内容,并测试每个字符是否属于ascii范围0x00到0x1F。它可以完成,但我想知道是否有更好的方法使用类型String的Java方法。

EDIT 我发现了一个可能对其他人有用的解决方案:使用Java方法String#ReplaceAll来替换或删除XML文档中的任何不需要的字符。

示例代码(我删除了一些必要的语句以避免混乱):

BufferedReader reader = null;
...
String line = reader.readLine().replaceAll("[\\x00-\\x1F]", "");

在这个例子中,我删除(即用空字符串替换),包含范围在0x00到0x1F范围内的不可打印字符。您可以更改方法#replaceAll()中的第二个参数,以使用您的应用程序所需的字符串替换字符。

答案 4 :(得分:0)

您的无效字符是否可能仅存在于值中而不是标记本身,即XML在概念上符合模式,但值尚未正确清理?如果是这样,那么重写InputStream来创建一个CleansingInputStream,用它们的XML等价替换你的无效字符呢?

答案 5 :(得分:0)

您的问题与XML无关:它涉及字符编码。它归结为每个字符串,无论是XML还是其他字符串,都由字节组成,你不知道这些字节代表什么字符,除非你被告知字符串具有什么字符编码。例如,如果供应商告诉你它是UTF-8并且它实际上是别的东西,那么你一定会遇到问题。在最好的情况下,一切正常,但有些字节被转换为“错误”字符。在最坏的情况下,您会遇到类似于您遇到的错误。

实际上,您的问题更严重:您的字符串包含的字节序列不代表任何字符编码中的字符。没有文本处理工具,更不用说XML解析器了,它可以帮助你。这需要字节级清理。