Преобразование XML-документа из Latin1 в UTF8 с использованием Java - PullRequest
1 голос
/ 21 декабря 2009

Я пытаюсь создать XML-документ (RSS-канал) и обработал все изгибы в нем, за исключением одной проблемы кодировки символов. Проблема в том, что я использую кодировку UTF-8 примерно так <?xml version="1.0" encoding="UTF-8"?>, за исключением того, что сам документ не кодируется в UTF-8.

Я использую пакет org.apache.ecs.xml для создания всех тегов. Затем я использую doc.output(stream), чтобы написать содержание. Этот метод, кажется, не записывает вывод с использованием UTF-8, и я не знаю, как это сделать. Пока я это не сделал, некоторые символы (британский фунт - это то, что я впервые заметил) не отображаются должным образом в большинстве читателей.

- Обновлено с дополнительной информацией -

Я решил использовать плохое решение (как описано в комментариях) для решения этой проблемы. Правильный ответ, кажется, не использовать библиотеку org.apache.ecs.xml. Спасибо всем за помощь. StackOverflow снова побеждает.

Ответы [ 5 ]

1 голос
/ 22 декабря 2009

Вот решение, которое придумал мой коллега, и я думаю, что это правильный способ сделать это, но что я знаю. Вместо использования doc.output(stream) мы использовали:

    try {
            IOUtils.write(doc.toString(), stream, "UTF-8");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

Если честно, я еще не до конца понимаю проблему, поэтому у меня, во-первых, проблемы. Похоже, что решение @ subtenante прошло и преобразовало любой символ, который UTF-8 не мог представить, и заменило его на юникодную сущность. Это решение, кажется, записывает в поток, используя кодировку UTF-8, как я изначально хотел для doc.output. Я не знаю точной разницы, просто оба решили мои проблемы. Будем благодарны за любые дальнейшие комментарии, которые помогут мне понять проблему.

1 голос
/ 21 декабря 2009

Любой шанс, что вы можете писать в Writer, а не в OutputStream ... таким образом, вы можете указать кодировку.

1 голос
/ 21 декабря 2009

Самый простой обходной путь, вероятно, будет изменять ваш код следующим образом:

XMLDocument doc = new XMLDocument(1.0,false,Charset.defaultCharset().toString());

Я предполагаю, что они просто используют кодировку по умолчанию для записи символов в поток. Поэтому передайте кодировку по умолчанию прологу, и все будет в порядке.

Я согласен с другими авторами, что это, вероятно, наименьшее из ваших опасений. Если посмотреть на исходный репозиторий для ECS, он, похоже, не обновлялся в течение четырех лет (аналогично и репозиторий "ECS2").

И немного саморекламы: если вы хотите создавать XML-документы с использованием простого интерфейса, у библиотеки Practical XML есть компоновщик. Для вывода используется стандартный механизм сериализации JDK.

0 голосов
/ 21 декабря 2009

Вот функция, которую я написал для преобразования всех не-ASCII-символов в соответствующие им объекты. Может помочь вам продезинфицировать часть содержимого PCDATA перед выводом.

/**
 * Creates xml entities for non ascii characters in the given String.
 */
public static String xmlEntitify(String in){

    StringBuffer b = new StringBuffer();

    for (int i=0;i<in.length();i++){

        Character c = in.charAt(i);
        if (c<128){
            b.append(c);
        }
        else if (c=='\ufeff'){
            // BOM character, just remove it
        }
        else {
            String cstr = Integer.toHexString(c).toUpperCase();
            while(cstr.length()<4){
                cstr="0"+cstr;
            }
            b.append("&#x");
            b.append(cstr);
            b.append(";");
        }
    }
    return b.toString();
}

Считайте ваш входной поток в String content и запишите в выходной поток xmlEntitify(content).

Ваш вывод гарантированно содержит только символы ASCII, больше никаких проблем с кодировкой.

UPDATE

Учитывая комментарии, я буду еще смелее: если вы не очищаете свои данные, вы вызываете проблемы. Я полагаю, вы по крайней мере уже заменяете символы < и & в своих PCDATA. Если нет, вам определенно следует. У меня есть другая версия вышеуказанного метода, которая вместо первого if имеет:

if (c<128 && c!='&' && c!='<' && c!='>' &&  c!='"'){
    b.append(c);
}

, чтобы эти символы также были преобразованы в соответствующие им объекты Unicode. Это преобразует все мои PCDATA в Unicode-дружественные строки только для ASCII. У меня больше не было проблем с кодированием, так как я использую эту технику. Я никогда не выводил XML PCDATA, который не был передан этим методом: это не сметает слона под ковер. Это просто избавление от проблемы, будучи настолько общим, насколько это возможно.

0 голосов
/ 21 декабря 2009

Я не знаком с этим пакетом, но из источника в Интернете я подозреваю, что он может быть сломан:

http://kickjava.com/src/org/apache/ecs/xml/XMLDocument.java.htm

содержит такие вещи, как

        for (int i=0; i<prolog.size(); i++) {
268             ConcreteElement e = (ConcreteElement)prolog.elementAt(i);
269             e.output(out);
270             // XXX really this should use line separator!
271 // XXX should also probably check for pretty print
272 // XXX also probably have difficulties with encoding

что говорит о проблемах.

Мы используем XOM (http://www.xom.nu), и в нем специально указан setEncoding () на его сериализаторе, поэтому я бы предложил изменить пакеты ...

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