java 读utf-8 xml_用Java和UTF-8編碼生成有效的XML。

I am using JAXP to generate and parse an XML document from which some fields are loaded from a database.

我正在使用JAXP生成和解析XML文檔,其中從數據庫中加載了一些字段。

Code to serialize the 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));

Code to parse the XML:

解析XML的代碼:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

factory.setNamespaceAware(true);

DocumentBuilder builder = factory.newDocumentBuilder();

Document doc = builder.parse("test.xml");

And I encounter the following exception:

我遇到了以下的例外:

[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)

The String text includes u-umlaut and o-umlaut (character codes 0xFC and 0xF6). These are the characters that are causing the error. When I escape the String myself to use ü and ö then the problem goes away. Other entities are automatically encoded when I write out the XML.

字符串文本包括u-umlaut和o-umlaut(字符代碼0xFC和0xF6)。這些是導致錯誤的字符。當我自己將字符串轉義為ü時;和& # xF6;然后問題就消失了。當我寫出XML時,其他實體會被自動編碼。

How do I get my output to be written / read properly without substituting these characters myself?

我怎樣才能在不使用這些字符的情況下正確地編寫/讀取輸出?

(I've read the following questions already:

(我已經讀過以下問題:

如何將字符從Oracle編碼到XML?

修復XML文件中的錯誤編碼)

2 个解决方案

#1

31

Use a FileOutputStream rather than a FileWriter.

使用FileOutputStream而不是FileWriter。

The latter applies its own encoding, which is almost certainly not UTF-8 (depending on your platform, it's probably Windows-1252 or IS-8859-1).

后者應用自己的編碼,幾乎肯定不是UTF-8(根據您的平台,可能是Windows-1252或is -8859-1)。

Edit (now that I have some time):

編輯(現在我有時間了):

An XML document without a prologue is permitted to be encoded as UTF-8 or UTF-16. With a prologue, it iss allowed to specify its encoding (the prologue can contain only US-ASCII characters, so prologue is always readable).

沒有序言的XML文檔可以編碼為UTF-8或UTF-16。通過序言,iss允許指定它的編碼(序言只能包含US-ASCII字符,所以序言總是可讀的)。

A Reader deals with characters; it will decode the byte stream of the underlying InputStream. As a result, when you pass a Reader to the parser, you are telling it that you've already handled the encoding, so the parser will ignore the prologue. When you pass an InputStream (which reads bytes), it does not make this assumption, and will look to the prologue to define the encoding -- or default to UTF-8/UTF-16 if it's not there.

讀者處理字符;它將解碼底層InputStream的字節流。因此,當您將閱讀器傳遞給解析器時,您是在告訴它您已經處理了編碼,因此解析器將忽略序言。當您傳遞一個InputStream(讀取字節)時,它不會做這樣的假設,並將查看序言以定義編碼——如果沒有UTF-8/UTF-16,則默認為UTF-8/UTF-16。

I've never tried reading a file that is encoded in UTF-16. I suspect that the parser will look for a Byte Order Mark (BOM) as the first 2 bytes of the file.

我從來沒有讀過用UTF-16編碼的文件。我懷疑解析器將查找字節順序標記(BOM)作為文件的前兩個字節。

#2

5

Well, for sure 0xFC and 0xF6 are not valid UTF-8 characters. These should have been finnesed to the two byte sequences: 0x3CBC and 0x3CB6.

當然,0xFC和0xF6不是有效的UTF-8字符。應該對這兩個字節序列進行檢查:0x3CBC和0x3CB6。

Most likely the problem is with the original source of the characters being defined as UTF-8 when they are not.

最可能的問題是字符的原始來源被定義為UTF-8,當它們不是。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值