将西里尔字符写入xml文件

时间:2012-07-12 09:57:01

标签: c libxml2 xmltextwriter

我正在使用xmlTextWriter中的libxml2来编写一些xml文件。我需要在其中写下西里尔字符。 我是这样做的:

xmlTextWriterStartDocument(writer, NULL, "utf-8", NULL);
...
snprintf(buf, sizeof(buf), "%s", "тест");
xmlTextWriterWriteAttribute(writer, 
                            (const xmlChar*)"test_attribute", 
                            (const xmlChar*)buf);

但是当我打开生成的xml文件时,我看到了我的文本的html表示,就像这样:test_attribute="тест"

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

您需要使用单独的utf-8编码器。

在snprintf()中,您的文本采用CP-1251(单字节ASCII时代编码),而不是UTF-8(可变宽度编码)。

请参阅此链接以获取参考实施:http://7maze.ru/node/29

评论是俄语,但您只需要转换表和

string convertToUtf8(const char* chars, int len)

最后的功能。

您使用的“тест”字符串在编码时应该看起来像“РўРчС_С”(绝对毫无意义)。

来自一个旧项目的旧C代码。它使用CP-866编码(MS-DOS中的另一种“流行”编码),但CP-1251的转换很简单。

/// CP866 to UTF-8
char *dosstrtou(char *buffer,const char *dosstr)
{
    char *buf1=buffer;
    while (*dosstr)
    {
        if ( (*dosstr>127)&&(*dosstr<176) )
        {
            *buf1=208;
            buf1++;
            *buf1 = (char)(*dosstr+16);
            dosstr++;
            buf1++;
            continue;
        }       
        if ( (*dosstr>223)&&(*dosstr<240) )
        {
            *buf1=209;
            buf1++;
            *buf1 = (char)(*dosstr-96);
            dosstr++;
            buf1++;
            continue;
        }       
        if (*dosstr==240)
        {
            *buf1=208;
            buf1++;
            *buf1=129;
            dosstr++;
            buf1++;
            continue;
        }       
        if (*dosstr==241)
        {
            *buf1=209;
            buf1++;
            *buf1=145;
            dosstr++;
            buf1++;
        }
        *buf1=*dosstr;
        buf1++;
        dosstr++;
    }
    *buf1='\0';
    return (buffer);
}

/// CP1251 to CP866
char *winstrtodos(char *buffer){
    char *ptr=buffer;
    while (*ptr!='\0')
    {
        if ( (*ptr>=0x80+0x40)&&(*ptr<=0xAF+0x40) )
            *ptr =(char)(*ptr-0x40);
        if ( (*ptr>=0xE0+0x10)&&(*ptr<=0xEF+0x10) )
            *ptr = (char)(*ptr-0x10);
        if (*ptr==0xA8) *ptr=0xF0;  
        if (*ptr==0xB8) *ptr=0xF1;
        ptr++;
    }
    return (buffer);
}

小心记忆。