DOM4J utf-8 кодирует умлаут (Ä, ü, ß) неправильно

Я использую DOM4j для разбора и написания XML-дерева, которое всегда находится в UTF-8.

Мой файл XML включает немецкие специальные символы. Разобрать их не проблема, но когда я записываю дерево в файл, специальные символы преобразуются в символы �.

Я не могу изменить кодировку файла XML, поскольку она ограничена UTF-8.

Код

SAXReader xmlReader = new SAXReader();
xmlReader.setEncoding("UTF-8");

Document doc = xmlReader.read(file);
doc.setXMLEncoding("UTF-8");
Element root = doc.getRootElement();

// manipulate doc

OutputFormat format = new OutputFormat();

format.setEncoding("UTF-8");

XMLWriter writer = new XMLWriter(new FileWriter(file), format);

writer.write(doc);
writer.close();

Ожидаемый результат

... 
<statementText>This is a test!Ä Ü ß</statementText>
...

Фактический результат

...
<statementText>This is a test!� � �</statementText>
...

person Jakob Sachs    schedule 18.06.2018    source источник
comment
Спасибо, что решил это!   -  person Jakob Sachs    schedule 18.06.2018


Ответы (1)


Вы передаете FileWriter в XMLWriter. Writer уже обрабатывает данные String или char[], поэтому он уже обрабатывает кодировку, что означает, что XMLWriter не имеет шансов повлиять на нее.

Кроме того, FileWriter является особенно проблематичным типом Writer, поскольку вы никогда не можете указать, какую кодировку он должен использовать, вместо этого он всегда использует кодировку платформы по умолчанию (которая часто является чем-то вроде ISO-8859-1 в Windows и UTF-8 в Linux). По этой причине его в принципе никогда не следует использовать.

Чтобы позволить XMLWriter применить то, что ему задано в качестве конфигурации, вместо этого передайте ему OutputStream (который обрабатывает byte[]). Наиболее очевидным для использования здесь будет FileOutputStream:

XMLWriter writer = new XMLWriter(new FileOutputStream(file), format);

Это даже задокументировано в JavaDoc для XMLWriter:

Предупреждение: использование вашего собственного Writer может привести к тому, что предпочтительная кодировка символов Writer будет игнорироваться. Если вы используете кодировки, отличные от UTF8, мы рекомендуем вместо этого использовать метод, который принимает OutputStream.

Возможно, предупреждение немного вводит в заблуждение, так как Writer может быть проблематичным, даже если вы собираетесь записывать данные UTF-8.

person Joachim Sauer    schedule 18.06.2018