29

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

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

4

6 回答 6

22

我使用了 Xalanorg.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();
}
于 2012-03-09T14:04:11.257 回答
10

我没有亲自使用过,但是 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 > data-clean.xml

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

于 2008-09-18T16:00:43.503 回答
8

我使用以下似乎对 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表示法,而不是不那么容易理解的表示法。

于 2011-10-11T13:32:55.967 回答
3

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

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

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

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

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

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

于 2011-11-15T06:23:08.410 回答
0

是否有可能您的无效字符仅存在于值中而不是标签本身,即 XML 理论上符合架构但值没有被正确清理?如果是这样,那么重写 InputStream 以创建一个 CleansingInputStream 用它们的 XML 等效字符替换您的无效字符呢?

于 2008-09-18T16:03:40.047 回答
0

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

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

于 2008-09-18T16:05:11.527 回答