在Java中剥离无效的XML字符

在Java中剥离无效的XML字符

Stripping Invalid XML characters in Java

我有一个XML文件,它是数据库的输出。 我正在使用Java SAX解析器来解析XML并以其他格式输出它。 XML包含一些无效字符,并且解析器抛出诸如"无效Unicode字符(0x5)"之类的错误

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


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

1
2
3
4
5
6
7
8
9
10
11
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();
}

我没有亲自使用它,但是Atlassian开发了一种命令行XML清理程序,它可以满足您的需求(它主要是为JIRA而设计的,但XML是XML):

Download atlassian-xml-cleaner-0.1.jar

Open a DOS console or shell, and locate the XML or ZIP backup file on your computer, here assumed to be called data.xml

Run:
java -jar atlassian-xml-cleaner-0.1.jar data.xml > data-clean.xml

This will write a copy of data.xml to data-clean.xml, with invalid characters removed.


我使用了以下正则表达式,该正则表达式似乎可以对JDK6正常工作:

1
2
3
Pattern INVALID_XML_CHARS = Pattern.compile("[^\\\\u0009\\\\u000A\\\\u000D\\\\u0020-\\\\uD7FF\\\\uE000-\\\\uFFFD\\uD800\\uDC00-\\uDBFF\\uDFFF]");
...
INVALID_XML_CHARS.matcher(stringToCleanup).replaceAll("");

在JDK7中,可能对于不在BMP之外的最后一个范围使用符号\\x{10000}-\\x{10FFFF}代替了不那么容易理解的\\uD800\\uDC00-\\uDBFF\\uDFFF符号。


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

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

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

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

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

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


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

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


是否有可能您的无效字符仅出现在值中,而不是标记本身,即XML在概念上符合架构,但值未得到正确清理?如果是这样,如何覆盖InputStream来创建CleansingInputStream,以将无效字符替换为XML等效字符?


推荐阅读

    linux移走文件命令?

    linux移走文件命令?,位置,文件,名称,软件,数据,命令,目录,文件夹,百度,环境,

    linux命令检清空文件?

    linux命令检清空文件?,系统,不了,名称,环境,文件夹,命令,文件,目录,指令,终

    linux命令不换行输出?

    linux命令不换行输出?,工作,地址,系统,情况,标准,命令,管理,网络,信息,目录,3

    linux的文件命令d?

    linux的文件命令d?,地址,情况,信息,工作,工具,命令,代码,文件,目录,控制台,Li

    更新文件命令linux?

    更新文件命令linux?,工作,系统,地址,信息,时间,命令,目录,基础,标准,网络,lin

    linux下读取文件命令?

    linux下读取文件命令?,系统,工作,地址,数字,图片,信息,网络,命令,文件,一致,l

    linux输出结果命令?

    linux输出结果命令?,标准,工作,系统,信息,命令,文件,百度,数字,环境,设备,lin

    linux字符转换命令?

    linux字符转换命令?,系统,工作,密码,信息,命令,基础,名称,软件,工具,电脑,Lin

    linux改文件夹名命令?

    linux改文件夹名命令?,名字,软件,命令,文件,系统,目录,目标,文件名,源文件,

    linux建文件命令格式?

    linux建文件命令格式?,系统,名字,名称,时间,密码,命令,文件,文件夹,不了,数

    下载文件的命令linux?

    下载文件的命令linux?,平台,工具,服务,密码,软件,网络,位置,代理,手机,工作,

    linux命令文件传输?

    linux命令文件传输?,系统,数据,命令,文件,基本知识,源文件,目录,目标,功能,

    linux文件全选命令?

    linux文件全选命令?,电脑,系统,环境,代码,平台,服务,快捷键,文件,命令,权限,l

    linux浏览文件类命令?

    linux浏览文件类命令?,系统,信息,数据,情况,命令,标准,时间,文件,概念,管理,

    linux打包文件夹命令?

    linux打包文件夹命令?,系统,工具,管理,图片,文件,命令,位置,软件,目录,格式,l

    linux中统计文件命令?

    linux中统计文件命令?,系统,信息,数据,情况,工作,文件,时间,档案,标准,名称,L

    linux获取命令输出行?

    linux获取命令输出行?,数字,工具,系统,数据,命令,文件,内容,文本,尾部,表示,L

    linux导入文件夹命令?

    linux导入文件夹命令?,系统,文件,信息,名称,工作,命令,文件夹,目录,发行,位

    linux输出字符串命令?

    linux输出字符串命令?,标准,基础,字符串,资料,简介,商业,数字,系统,命令,汉