告诉SAX Parser忽略无效字符?

时间:2009-10-19 05:57:08

标签: java xml parsing sax

SAX继续死于以下异常:

Invalid byte 2 of 3-byte UTF-8 sequence

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

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

5 个答案:

答案 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)