Создание правильного XML с кодировкой Java и UTF-8 - PullRequest
21 голосов
/ 14 января 2009

Я использую 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)

Текст строки включает в себя u-umlaut и o-umlaut (коды символов 0xFC и 0xF6). Это символы, которые вызывают ошибку. Когда я избегаю String, я использую & # xFC; и & # xF6; тогда проблема уходит. Другие объекты автоматически кодируются, когда я записываю XML.

Как получить правильную запись / чтение моего вывода, не заменяя эти символы самостоятельно?

(я уже читал следующие вопросы:

Как кодировать символы из Oracle в XML?

Восстановление неправильной кодировки в файлах XML )

Ответы [ 2 ]

31 голосов
/ 14 января 2009

Используйте 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 байта файла.

5 голосов
/ 14 января 2009

Ну, наверняка 0xFC и 0xF6 недопустимы UTF-8 символов. Они должны были быть ограничены двумя байтовыми последовательностями: 0x3CBC и 0x3CB6.

Скорее всего, проблема в том, что исходный символ определяется как UTF-8, а не *. 1009 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...