Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Разбор XML с кодировкой windows-1251, [Android] 
V
    Опции темы
math64
Дата 25.12.2015, 09:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



В Андроиде пробую прочитать xml:
Код

       try {
           DefaultHandler documentHandler = new DefaultHandler() { ... };
           SAXParserFactory factory = SAXParserFactory.newInstance();
           InputSource source = new InputSource(stream);
           SAXParser parser = factory.newSAXParser();
           documentHandler.setDocumentLocator(null);
           parser.parse(source, documentHandler);
       } catch (ParserConfigurationException ex) {
       } catch (SAXException ex) {
       } catch (IOException ex) {
       }

Если xml в кодировке 1251
Код

<?xml version="1.0" encoding="windows-1251"?>

то чтение оканчивается на первой русской букве. С utf-8 все нормально. Заранее кодировка неизвестна.

Это сообщение отредактировал(а) math64 - 25.12.2015, 14:04
PM   Вверх
AntonSaburov
Дата 25.12.2015, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Штурман
****


Профиль
Группа: Модератор
Сообщений: 5658
Регистрация: 2.7.2002
Где: Санкт-Петербург

Репутация: 51
Всего: 118



PM MAIL WWW ICQ   Вверх
math64
Дата 25.12.2015, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Код

org.apache.harmony.xml.ExpatParser$ParseException: At line 7, column 16: not well-formed (invalid token)

16 колонка это '>'  перед русской буквой.
Код

    <first-name>Александр</first-name>

Вставка
Код

source.setEncoding("windows-1251");

не помогает.
PM   Вверх
LSD
Дата 25.12.2015, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 209
Всего: 537



Запакуй XML файл и выложи сюда.
Какая версия Java используется?


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
math64
Дата 25.12.2015, 11:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



javac: 1.7.0_80
Android 4.0.4


Присоединённый файл ( Кол-во скачиваний: 1 )
Присоединённый файл  Блок_А._Избранное.fb2 358,76 Kb
PM   Вверх
math64
Дата 25.12.2015, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



PS: там
Код

<image xlink:href="#_0.jpg" />

вместо
Код

<image l:href="#_0.jpg" />

но до этого дело не доходит

Это сообщение отредактировал(а) math64 - 25.12.2015, 11:59
PM   Вверх
math64
Дата 25.12.2015, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Добавил в свой файл main() - запустил на компе, работает. Дело в Андроиде.
PS: Вывел список кодировок на устройстве.
Код

java.nio.charset.Charset.availableCharsets().keySet().toArray();

windows-1251 присутствует.

Это сообщение отредактировал(а) math64 - 25.12.2015, 13:19
PM   Вверх
LSD
Дата 25.12.2015, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 209
Всего: 537



Цитата(math64 @  25.12.2015,  12:56 Найти цитируемый пост)
Android 4.0.4

Блин! Раньше была проблема что JavaScript от Java не отличали, теперь не понимают что Android это не Java.

Код

        DefaultHandler documentHandler = new DefaultHandler() {};
        SAXParserFactory factory = SAXParserFactory.newInstance();
        InputSource source = new InputSource(new InputStreamReader(stream, Charset.forName("windows-1251")));
        SAXParser parser = factory.newSAXParser();
        documentHandler.setDocumentLocator(null);
        parser.parse(source, documentHandler);



--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
math64
Дата 25.12.2015, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Цитата(LSD @  25.12.2015,  13:45 Найти цитируемый пост)
Блин! Раньше была проблема что JavaScript от Java не отличали, теперь не понимают что Android это не Java.

Я это сразу указал, в первом сообщение.
Цитата(LSD @  25.12.2015,  13:45 Найти цитируемый пост)
 
Код

       InputSource source = new InputSource(new InputStreamReader(stream, Charset.forName("windows-1251")));


Так работает. Но как сделать, чтобы кодировка определялась автоматически?


PM   Вверх
LSD
Дата 25.12.2015, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 209
Всего: 537



Цитата(math64 @  25.12.2015,  14:52 Найти цитируемый пост)
Но как сделать, чтобы кодировка определялась автоматически?

Надо ее прочитать из заголовка. К.О.
Кодировки можно разделить на 2 части: UTF-16(32) и остальные.
Первые бывают big/little endian и там надо прочитать первые 2 байта, понять BOM это или символ <, исходя из этого определить byte order, прочитать весь пролог и оттуда вытащить кодировку.
Если второе, то в таких кодировках первые 127 символов совпадают с ASCII и значит пролог можно читать как ASCII, опять же читаем и вытаскиваем кодировку.

Если лень самому такое колхозить, можно поискать сторонний парсер, но тут надо понимать что XML парсер это очень большая штука и можно нарваться на ограничение в 65К методов. Надо искать что-то маленькое.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
math64
Дата 13.1.2016, 08:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



примерно так:
Код

       stream = new BufferedInputStream( stream, 8192);
       InputSource source =
              new InputSource(
                  new InputStreamReader(
                      stream,
                      java.nio.charset.Charset.forName( detectEncoding(stream) ) ) );

    String detectEncoding(InputStream in) throws IOException {
        // return "windows-1251";
        String encoding = null;
        in.mark( 400 );
        int ignoreBytes = 0;
        boolean readEncoding = false;
        byte[] buffer = new byte[ 400 ];
        int read = in.read( buffer, 0, 4 );
        int n = ((buffer[0] & 0xFF) << 24) |
                ((buffer[1] & 0xFF) << 16) |
                ((buffer[2] & 0xFF) << 8) |
                (buffer[3] & 0xFF);
        switch( n ) {
            case 0x0000FEFF:
                ignoreBytes = 4;
                encoding = "UTF_32BE";
                break;
            case 0x0000003C:
                encoding = "UTF_32BE";
                readEncoding = true;
                break;
            case 0x003C003F:
                encoding = "UnicodeBigUnmarked";
                readEncoding = true;
                break;
            case 0xFFFE0000:
                ignoreBytes = 4;
                encoding = "UTF_32LE";
                break;
            case 0x3C000000:
                //
                encoding = "UTF_32LE";
                break;
            case 0x3C003F00: // <?
                encoding = "UnicodeLittleUnmarked";
                break;
            case 0x3C3F786D: // <?xm
                readEncoding = true;
                encoding = "ASCII";
                break;
            default:
                if ( (n >>> 8) == 0xEFBBBF) {
                    encoding = "UTF8";
                    ignoreBytes = 3;
                    break;
                }
                if ( (n >>> 24) == 0x3C) {
                    readEncoding = true;
                    break;
                }
                switch ( n >>> 16 ) {
                    case 0xFFFE:
                        ignoreBytes = 2;
                        encoding = "UnicodeLittleUnmarked";
                        break;
                    case 0xFEFF:
                        ignoreBytes = 2;
                        encoding = "UnicodeBigUnmarked";
                        break;
                }
        }
        if( encoding == null ) {
            encoding = System.getProperty( "file.encoding" );
        }
        if( readEncoding ) {
            read = in.read( buffer, 4, buffer.length - 4 );
            String s = new String( buffer, 4, read, encoding );
            int pos = s.indexOf( "encoding" );
            if( pos == -1 ) {
                encoding = System.getProperty( "file.encoding" );
            } else {
                char delim;
                int start = s.indexOf( "?>" );
                if( start != -1 )
                    s = s.substring( 0, start );
                start = s.indexOf( delim = '\'', pos );
                if( start == -1 )
                    start = s.indexOf( delim = '"', pos );
                if( start == -1 )
                    throw new IOException( "Parser - not an XML file" );
                int end = s.indexOf( delim, start + 1 );
                if( end == -1 )
                    throw new IOException( "Parser - not an XML file" );
                encoding = s.substring( start + 1, end );
            }
        }
        in.reset();
        while( ignoreBytes-- > 0 )
            in.read();
        return encoding;
    }

PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1709 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.