Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中剥离无效的XML字符_Java_Xml - Fatal编程技术网

在Java中剥离无效的XML字符

在Java中剥离无效的XML字符,java,xml,Java,Xml,我有一个XML文件,它是数据库的输出。我使用JavaSAX解析器解析XML并以不同的格式输出它。XML包含一些无效字符,并且解析器正在抛出类似“无效Unicode字符(0x5)”的错误 除了逐行预处理文件并替换它们之外,还有什么好方法可以去除所有这些字符吗?到目前为止,我遇到了3个不同的无效字符(0x5、0x6和0x7)。这是一个~4gb的数据库转储,我们要处理它很多次,所以每次我们得到一个新的转储,要在它上运行预处理器,都要额外等待30分钟,这将是一件痛苦的事情,这不是我第一次遇到这个问题。我

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


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

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

下载

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

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

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


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

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


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

我使用以下regexp,它似乎与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中,可以对BMP之外的最后一个范围使用符号
\x{10000}-\x{10FFFF}
,而不是不那么容易理解的
\uD800\uDC00-\uDBFF\uDFFF
符号。

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

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

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

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


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

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

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();
}
公共静态字符串stripInvalidXmlCharacters(字符串输入){
StringBuilder sb=新的StringBuilder();
对于(int i=0;i
其他人的链接断了吗?@controlnetictwerkguroorc。下面是我找到的另一个链接:如果为marketplace构建一个插件,那么在com.atlassian.core.util.xml.XMLCleaningReaderMessage from the future(2020)上可以找到替换无效字符的同一个类-第二个链接对我很有用,这个JAR解决了我遇到的一个严重问题,即数千个包含各种非法字符的XML文件。通过这个实用程序运行它们使它们标准化,并使它们可以通过Python的lxml库进行解析。未来谢谢你。我认为这一条不适用于代理字符:
XMLChar#isValid()
将分别为高部分和低部分返回false,但如果这两个部分一起有效,则返回true。如果文件包含无效字符,则它不是XML文件。请it的创建者在将来只创建格式良好的XML。我过去经常遇到这个问题。人们似乎不理解XML需要格式良好且不包含垃圾。我100%同意这一点。不幸的是,这并不总是可能的(不称职的技术人员、合同措辞等),字符有什么意义吗?假设它们不是随机损坏,那么剥离它们不会删除信息吗?
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();
}