我正在使用JAXP生成和解析XML文档,从该文档从数据库加载一些字段.
用于序列化XML的代码:
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document doc = builder.newDocument(); Element root = doc.createElement("test"); root.setAttribute("version", text); doc.appendChild(root); DOMSource domSource = new DOMSource(doc); TransformerFactory tFactory = TransformerFactory.newInstance(); FileWriter out = new FileWriter("test.xml"); Transformer transformer = tFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); transformer.transform(domSource, new StreamResult(out));
解析XML的代码:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse("test.xml");
我遇到以下异常:
[Fatal Error] test.xml:1:4: Invalid byte 1 of 1-byte UTF-8 sequence. Exception in thread "main" org.xml.sax.SAXParseException: Invalid byte 1 of 1-byte UTF-8 sequence. at org.apache.xerces.parsers.DOMParser.parse(Unknown Source) at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source) at javax.xml.parsers.DocumentBuilder.parse(Unknown Source) at com.test.Test.xml(Test.java:27) at com.test.Test.main(Test.java:55)
String文本包括u-umlaut和o-umlaut(字符代码0xFC和0xF6).这些是导致错误的字符.当我自己逃避String时使用ü 和ö 然后问题就消失了.当我写出XML时,其他实体会自动编码.
如何在不自行替换这些字符的情况下正确地写入/读取输出?
(我已经阅读了以下问题:
如何将字符从Oracle编码为XML?
修复XML文件中的错误编码)
使用FileOutputStream而不是FileWriter.
后者应用自己的编码,几乎肯定不是UTF-8(取决于您的平台,它可能是Windows-1252或IS-8859-1).
编辑(现在我有一些时间):
允许将没有序言的XML文档编码为UTF-8或UTF-16.通过序言,它允许指定其编码(序言只能包含US-ASCII字符,因此序言总是可读的).
读者处理人物; 它将解码底层InputStream的字节流.因此,当您将Reader传递给解析器时,您告诉它您已经处理了编码,因此解析器将忽略该序言.当你传递一个InputStream(它读取字节)时,它不会做出这个假设,并会查看序言来定义编码 - 如果它不存在则默认为UTF-8/UTF-16.
我从未尝试过读取以UTF-16编码的文件.我怀疑解析器会查找字节顺序标记(BOM)作为文件的前2个字节.
嗯,肯定0xFC
并且0xF6
不是有效的UTF-8
字符.这些应该是两个字节序列:0x3CBC
和0x3CB6
.
最有可能的问题是将字符的原始来源定义为UTF-8
不是.