SAX继续死于以下异常:
Invalid byte 2 of 3-byte UTF-8 sequence
问题是它大多是正确的UTF-8编码,但它有一些错误。我们无法获得该文件的新版本,我们必须使用此文件。
那么我们如何告诉SAX忽略无效字符序列,或清理UTF-8文件以使其没有无效的UTF-8序列?
答案 0 :(得分:3)
您可以在SAX读取之前过滤流。 创建一个InputStream,它读取您的流并删除无效字符。
答案 1 :(得分:2)
我建议您将文件清理为完全单独的步骤,将其解析为XML。
UTF-8是一个相当容易理解的编码; this web page显示了如何形成UTF-8。我建议你写一个程序,它读入你的输入文件并写出一个新文件。它将逐字节读取,只有在看到它已经有效形成时才写出一个字符。当它看到一个无效字节时,它会写出字符串“UTF8ERROR”或其他一些容易找到的令牌,这些令牌在输入数据中不会自然出现。然后它将跳过角色的其余部分。
之后,您可以检查错误发生的位置并修复数据......然后正常解析。
通过这种方式,您可以看到错误的广泛程度,看看它们是否存在任何模式,并且可能能够纠正它们。如果你要从同一来源收到更多数据,我强烈建议你告诉他们这个问题......这可能表明他们有更严重的问题。
答案 2 :(得分:1)
SAX(以及其他XML工具)旨在用于格式良好(或必需的有效)XML。当输入格式不正确(包括不符合编码)时,它们会故意抛出错误或异常。因此,正如其他答案所暗示的那样,您必须使用单独的步骤来清理输入。
(类似地,SAX会抛出错误的HTML,而不是格式良好的XML,例如缺少结束标记)。
答案 3 :(得分:0)
我想这对你没什么帮助,但也许其他人想知道:
我最近在检索使用ISO-8859-1标头提供的UTF-8 XML文件时遇到了同样的异常。解决方案是通过String.getBytes(charset)手动指定UTF-8:
public Document parseRequest(HttpServletRequest request) {
DocumentBuilderFactory builder = DocumentBuilderFactory.newInstance();
DataInputStream dataStream = new DataInputStream(request.getInputStream());
String xml = dataStream.readUTF();
ByteArrayInputStream byteStream = new ByteArrayInputStream(xml.getBytes("UTF-8"));
return builder.newDocumentBuilder().parse(byteStream);
}
编辑:..甚至更简单:
public Document parseRequest(HttpServletRequest request) {
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
Reader reader = new InputStreamReader(request.getInputStream(), "UTF-8");
InputSource source = new InputSource(reader);
return domFactory.newDocumentBuilder().parse(source);
}
答案 4 :(得分:0)
你能不能以某种方式将java.nio.charset.CharsetDecoder与InputStreamReader(CharsetDecoder dec中的InputStream)一起使用?
如何处理解码错误 取决于所要求的行动 描述的那种错误 通过一个实例 CodingErrorAction类。可能 错误动作是忽略的 错误的输入,报告错误 通过返回的调用者 CoderResult对象,或替换 错误的输入与当前值 替换字符串。该 替换具有初始值 “\ uFFFD”;它的价值可能会改变 replaceWith方法。
(来自CharsetDecoder javadoc)