我们正在使用JAXB解析XML文档并收到此错误:
[org.xml.sax.SAXParseException: Invalid byte 1 of 1-byte UTF-8 sequence.]
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:315)
这究竟是什么意思,我们如何解决这个问题?
我们正在执行以下代码:
jaxbContext = JAXBContext.newInstance(Results.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
unmarshaller.setSchema(getSchema());
results = (Results) unmarshaller.unmarshal(new FileInputStream(inputFile));
更新
问题似乎是由于XML文件中的这个“有趣”字符:¿
为什么会导致这样的问题?
更新2
文件中有两个奇怪的字符。它们位于文件的中间。请注意,该文件是基于数据库中的数据创建的,并且这些奇怪的字符以某种方式进入数据库。
更新3
以下是完整的XML代码段:
<Description><![CDATA[Mt. Belvieu ¿ Texas]]></Description>
更新4
请注意,没有<?xml ...?>
标头。
特殊字符的HEX是BF
答案 0 :(得分:3)
所以,你的问题是当你的文件使用其他编码时,JAXB将没有<?xml ...?>
标题的XML文件视为UTF-8(如果0xBF
,则可能是ISO-8859-1或Windows-1252字符实际上意味着¿
)。
如果您可以更改文件的生产者,可以添加<?xml ...?>
标头和实际编码规范,或者只使用UTF-8编写文件。
如果无法更改生成器,则必须使用InputStreamReader
和明确的编码规范,因为(不幸的是)JAXB不允许更改其默认编码:
results = (Results) unmarshaller.unmarshal(
new InputStreamReader(new FileInputStream(inputFile), "ISO-8859-1"));
但是,这个解决方案很脆弱 - 它在带有<?xml ...?>
标头且具有不同编码规范的输入文件上失败。
答案 1 :(得分:1)
这可能是Byte Order Mark (BOM),并且是UTF文件开头的特殊字节序列。坦率地说,它们是屁股的痛苦,在与.net系统交互时似乎特别常见。
尝试重新编写代码以使用Reader
而不是InputStream
:
results = (Results) unmarshaller.unmarshal(new FileReader(inputFile));
Reader
可识别UTF,可能会更好地刺激它。更简单地说,将File
直接传递给Unmarshaller
,让JAXBContext
担心它:
results = (Results) unmarshaller.unmarshal(inputFile);
答案 2 :(得分:0)
听起来好像你的XML是用UTF-16编码的,但是这个编码没有传递给Unmarshaller。使用Marshaller你可以使用marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-16");
来设置它,但是因为Unmarshaller不需要支持任何属性,我不确定除了确保你的XML文档在encoding="UTF-16"
中有<?xml?>
之外的其他方法。 1}}元素。