4

SAX 在以下异常中不断死亡:

Invalid byte 2 of 3-byte UTF-8 sequence

问题在于它大部分是正确的 UTF-8 编码,但其中有一些错误。我们无法获得该文件的新版本,我们必须使用该文件。

那么我们如何告诉 SAX 忽略无效的字符序列,或者清理 UTF-8 文件以使其没有无效的 UTF-8 序列?

4

5 回答 5

3

您可以在 SAX 读取流之前对其进行过滤。创建一个 InputStream 读取您的流并删除无效字符。

于 2009-10-19T06:02:41.167 回答
2

我建议您将文件清理为与将其解析为 XML完全不同的步骤。

UTF-8 是一种相当容易理解的编码;这个网页显示了 UTF-8 是如何形成的。我建议您编写一个程序来读取您的输入文件并写出一个新文件。它将一个字节一个字节地读取,只有当它看到它已经被有效地形成时才写出一个字符。当它看到一个无效字节时,它会写出字符串“UTF8ERROR”或其他一些不会在输入数据中自然出现的容易找到的标记。然后它会跳过角色的其余部分。

之后,您可以检查错误发生的位置并修复数据......然后正常解析它。

通过这种方式,您将看到错误的广泛性,看看它们是否有任何模式,并有可能纠正它们。如果您要从同一来源收到更多数据,我强烈建议您告诉他们这个问题......这可能表明他们方面存在更严重的问题。

于 2009-10-19T06:06:43.653 回答
1

SAX(和其他 XML 工具)旨在处理格式良好(或在需要时有效)的 XML。当输入格式不正确(包括未能符合编码)时,它们会故意抛出错误或异常。因此,正如其他答案所建议的那样,您必须使用单独的步骤来清理输入。

(类似地,SAX 会抛出格式不正确的 XML 的 HTML 错误,例如缺少结束标记)。

于 2009-10-19T06:10:38.653 回答
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);
}
于 2009-11-04T14:36:48.517 回答
0

你能用某种方式 java.nio.charset.CharsetDecoder一起使用吗?InputStreamReader(InputStream in, CharsetDecoder dec)

如何处理解码错误取决于为该类型错误请求的操作,该操作由 CodingErrorAction 类的实例描述。可能的错误动作是忽略错误输入,通过返回的 CoderResult 对象向调用者报告错误,或者用替换字符串的当前值替换错误输入。替换具有初始值“\uFFFD”;它的值可以通过 replaceWith 方法更改。

(来自CharsetDecoderjavadoc)

于 2009-11-06T08:31:37.687 回答