Создание допустимого XML с кодировкой Java и UTF-8
Я использую 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). Это символы, вызывающие ошибку. Когда я убегаю от строки, чтобы использовать & #xFC; и & # xF6; то проблема уходит. Другие объекты автоматически кодируются, когда я выписываю XML.
Как заставить мой вывод быть написанным/прочитанным правильно, не заменяя эти символы самостоятельно?
(Я уже читал следующие вопросы:
Как кодировать символы из Oracle в XML?
Исправление неправильной кодировки в файлах XML)
Ответы
Ответ 1
Используйте FileOutputStream, а не FileWriter.
Последний применяет свою собственную кодировку, которая почти наверняка не является UTF-8 (в зависимости от вашей платформы, вероятно, Windows-1252 или IS-8859-1).
Изменить (теперь у меня есть время):
Документ XML без пролога разрешается кодировать как UTF-8 или UTF-16. С прологом разрешено указывать его кодировку (пролог может содержать только символы US-ASCII, поэтому пролог всегда читается).
A Reader имеет дело с символами; он будет декодировать поток байтов базового InputStream. В результате, когда вы передаете Reader в парсер, вы говорите, что вы уже обработали кодировку, поэтому анализатор будет игнорировать пролог. Когда вы передаете InputStream (который читает байты), он не делает этого предположения и будет смотреть на пролог, чтобы определить кодировку - или по умолчанию UTF-8/UTF-16, если он там отсутствует.
Я никогда не пробовал читать файл, закодированный в UTF-16. Я подозреваю, что синтаксический анализатор будет искать знак байта (BOM) как первые 2 байта файла.
Ответ 2
Ну, наверняка 0xFC
и 0xF6
недействительны UTF-8
символы. Они должны быть привязаны к двум байтовым последовательностям: 0x3CBC
и 0x3CB6
.
Скорее всего, проблема заключается в том, что исходный источник символов определяется как UTF-8
, когда они не являются.