Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Expat поддержка кодировок


Автор: becks 24.1.2012, 12:10
Добрый день, коллеги! 
Мне необходимо парсить Xml-ки больших размеров, для этих целей прошерстил интернет и остановился на парсере Expat. Быстренько написал тестовый примерчик, все отлично, все понятно. Как только в тестовой xml стал использовать русские символы, появились проблемы на выходе - крокозябры.

Нашел ответ в интернете по моему вопросу: http://www.rsdn.ru/forum/src/489745.hot.aspx

Сделал все как там написано - итог прежний, крокозябры.

Может кто решал вопрос с кодировками в expat , прошу помощи.

Спасибо.

Автор: bsa 24.1.2012, 12:22
becks, а какая кодировка указана в тестовой XML?

Автор: becks 24.1.2012, 12:28
Цитата(bsa @ 24.1.2012,  12:22)
becks, а какая кодировка указана в тестовой XML?

windows-1251

Автор: becks 24.1.2012, 12:47
Вот тестовая XML:

Код

<?xml version="1.0" encoding="windows-1251"?> 
<x y="Привет1" z="Мир2">
   <y>zz</y> 
   <z>zz</z> 
</x>


Вот, что имеем на выходе:

tag=x userdata=(null)
        attrib y='Р?С?РёР?РчС'1'
        attrib z='Р?РёС?2'
 |->tag=y userdata=(null)
 |->tag=z userdata=(null)

Крокозябры, соответственно,  Привет и Мир.

Чтобы было более наглядно вот код которое это дело генерит:

main

Код

int main (void)
{
    int done, len;
    
    // Создание нового объекта парсера
    first = XML_ParserCreate(NULL);

    // Установка обработчика начального и конечного тегов
    XML_SetElementHandler(first, start, end);

    // Настройка кодировок обработчик, отсутствующих в комплекте
    XML_SetUnknownEncodingHandler(first, unknownEncoding, NULL);

    FILE * f_stream;
    errno_t err;

    if( (err  = fopen_s( &f_stream, "1.xml", "r" )) !=0 )
    {
        printf( "Не могу открыть файл!\n" );
        return 2;
    }

    do
    {
        len = fread(Buff, 1, BUFFSIZE, f_stream);
        done = feof(f_stream);
        XML_Parse(first, Buff, len, done);
    } while (!done);

    XML_ParserFree(first);

    if(f_stream)
     fclose(f_stream);

    return 0;
}



start и end

Код

// ---------------------------------------------------------------------------
// Функция обработчика открывающего тега
// ---------------------------------------------------------------------------
//    data - пользовательские данные    
//    tag - имя тега    
//    aAttrs - массив пар атрибутов и их значений    
// ---------------------------------------------------------------------------
static void XMLCALL start(void *data, const char *tag, const char **attr)
{
    int i;
    for (i = 0; i < Depth; i++) printf(" |->");
    printf("tag=%s userdata=%s\n", tag, (char*)data);

    for (i = 0; attr[i]; i += 2)
    {
        printf("\tattrib %s='%s'\n", attr[i], attr[i + 1]);
    }
    Depth++;
}


// ---------------------------------------------------------------------------
// Функция обработчика закрывающего тега
// ---------------------------------------------------------------------------
//    data - пользовательские данные    
//    tag - имя тега    
// ---------------------------------------------------------------------------
static void XMLCALL end(void *userdata, const char *tag)
{
    Depth--;
}



ну и поддержка кодировок как по ссылке сверху.

Автор: feodorv 24.1.2012, 12:53
Цитата(becks @  24.1.2012,  12:47 Найти цитируемый пост)
        attrib y='Р?С?РёР?РчС'1'
        attrib z='Р?РёС?2'

На вид UTF-8...

Автор: bsa 24.1.2012, 15:05
expat, видимо, преобразовал кодировку к UTF-8 (это вполне грамотное решение). Если тебе эта кодировка не подходит, то стоит самостоятельно преобразовать в нужную.

Автор: becks 6.2.2012, 09:36
Цитата

expat, видимо, преобразовал кодировку к UTF-8 (это вполне грамотное решение).


Да, проверил, так и есть

Цитата

Если тебе эта кодировка не подходит, то стоит самостоятельно преобразовать в нужную.


Теперь так и делаю, вопрос решен.

Большое спасибо.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)