有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java验证XML文档会导致“1字节UTF8序列中的1字节无效”

我使用内部使用Saxon的Probatron4j,根据Schematron样式表验证一些XML文件。在大多数情况下,这很好,但偶尔,处理会因错误而崩溃

org.xml.sax.SAXParseException: Invalid byte 1 of 1-byte UTF-8 sequence.

我的研究表明,这条信息通常表明(没有特定的顺序)

  • 明显无效的数据(例如,试图像读取XML文件一样读取ZIP文件)
  • 存在byte order marks
  • UTF-8中不合法字符的存在;或者
  • 一种声称是UTF-8编码的文件

这些都不适用于我正在处理的文档。我在程序执行期间检查了字节数组形式的输入,它不包含BOM或任何非ASCII字符

在处理30kb文档的过程中,大约有五分之一的时间会在一个不起眼的英语句子(我说的“不起眼”,意思是所有字节都在32(空格)和122(小写z)之间)上崩溃;换句话说,标准键盘字符)。这篇文章的末尾是被认为有问题的元素的字节

奇怪的是,失败的文档是通过从一个更大的文档中删除几个元素生成的,而该文档由相同的代码干净地处理

我知道异常是在实现org.xml.saxXMLReader接口的对象的parse(InputSource input)方法中引发的。根据the JavadocSAXException表示

Any SAX exception, possibly wrapping another exception.

在调试器中检查异常表明不存在包装异常

是什么导致了这个错误

编辑:

[60, 80, 97, 114, 97, 103, 114, 97, 112, 104, 62, 69, 120, 101, 99, 117, 116,
 105, 118, 101, 32, 83, 117, 109, 109, 97, 114, 121, 58, 32, 70, 114, 111, 109,
 32, 49, 55, 53, 52, 32, 116, 111, 32, 49, 55, 54, 51, 13, 10, 32, 32, 32, 32,
 32, 32, 32, 32, 32, 32, 32, 32, 69, 117, 114, 111, 112, 101, 32, 97, 110, 100,
 32, 116, 104, 101, 32, 65, 109, 101, 114, 105, 99, 97, 115, 32, 119, 101, 114,
 101, 32, 99, 97, 117, 103, 104, 116, 32, 117, 112, 32, 105, 110, 32, 97, 32, 99,
 111, 110, 102, 108, 105, 99, 116, 32, 98, 101, 116, 119, 101, 101, 110, 32, 69,
 110, 103, 108, 97, 110, 100, 44, 32, 117, 110, 100, 101, 114, 32, 75, 105, 110,
 103, 32, 71, 101, 111, 114, 103, 101, 32, 73, 73, 44, 32, 97, 110, 100, 32, 70,
 114, 97, 110, 99, 101, 44, 32, 117, 110, 100, 101, 114, 32, 75, 105, 110, 103,
 32, 76, 111, 117, 105, 115, 32, 88, 86, 46, 32, 73, 110, 32, 69, 117, 114, 111,
 112, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 116, 104, 105,
 115, 32, 112, 101, 114, 105, 111, 100, 32, 119, 97, 115, 32, 107, 110, 111, 119,
 110, 32, 97, 115, 32, 116, 104, 101, 32, 83, 101, 118, 101, 110, 32, 89, 101,
 97, 114, 115, 39, 32, 87, 97, 114, 59, 32, 105, 110, 32, 78, 111, 114, 116, 104,
 32, 65, 109, 101, 114, 105, 99, 97, 32, 105, 116, 32, 99, 97, 109, 101, 32, 116,
 111, 32, 98, 101, 32, 99, 97, 108, 108, 101, 100, 32, 116, 104, 101, 32, 70,
 114, 101, 110, 99, 104, 32, 97, 110, 100, 32, 73, 110, 100, 105, 97, 110, 32,
 87, 97, 114, 46, 32, 73, 116, 32, 119, 97, 115, 32, 97, 32, 99, 111, 110, 102,
 108, 105, 99, 116, 32, 111, 118, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32,
 32, 32, 32, 32, 32, 116, 114, 97, 100, 101, 32, 97, 110, 100, 32, 108, 97, 110,
 100, 46, 60, 47, 80, 97, 114, 97, 103, 114, 97, 112, 104, 62]

异常在第三次出现109之后抛出


共 (2) 个答案

  1. # 1 楼答案

    我已经解决了这个问题。尽管Java在内部使用UTF-8作为String对象,但String类的getBytes()方法将在系统的默认编码中生成字节,除非您明确指定需要UTF-8(或它理解的其他编码方案)

    我不完全确定这是如何或为什么解决这个问题的,因为抛出异常的位置附近的字节——问题末尾的字节——都是有效的UTF-8字节,但它似乎有固定的东西

    我能想到的唯一可能的原因是,我之前在文件中漏掉了一个无效字节,这使事情搞砸了,但没有立即导致崩溃。我正在从ByteArrayInputStream读取字节,因此程序可能会一次从缓冲区读取一大块,这会将pos标记设置为超出假设的坏字符所在位置的位置