随笔-59  评论-36  文章-0  trackbacks-0
(写次笔记的目的除了对知识点进行笔记外,还有就是希望能够帮助和我一样有遇到类似问题的朋友。)

刚接触tinyxml时,对于编码问题没怎么注意,但就是这个没有被我注意的问题,在暗地里向我放“黑枪”,耗了我不少时间。

现在就来说说我遇到的问题,以及我的解决方法。

如有不对的地方,恳请指正,小弟在这先谢谢了。

对于如下代码,
void Write()
{
    TiXmlDocument doc ;
    doc.LinkEndChild(
new TiXmlDeclaration("1.0" , "utf-8",""));
    TiXmlElement 
*pele = new TiXmlElement("ROOT");
    TiXmlElement 
*psubele = new TiXmlElement("First-element");

    psubele
->LinkEndChild(new TiXmlText("测试"));
    pele
->LinkEndChild(psubele);
    doc.LinkEndChild(pele);

    doc.SaveFile(
"test.xml");
}

生成的test.xml文件如果直接用IE查看,则会提示说遇见无效字符。之所以这样是因为,当文件进行保存时,文件的实际编码是ansi,而在ie进行解读时会根据声明中指定的编码utf-8来进行解释,对于英文字母来说utf-8和ansi是兼容的,但因为其中有汉字,所以用utf-8来解释编码为ansi的汉字就会出现乱码的问题,从而使得ie提示说遇见无效字符。

而解决的方法是,将写入的中文字符串转为utf-8编码
void Write()
{
    TiXmlDocument doc ;
    doc.LinkEndChild(
new TiXmlDeclaration("1.0" , "utf-8",""));
    TiXmlElement 
*pele = new TiXmlElement("ROOT");
    TiXmlElement 
*psubele = new TiXmlElement("First-element");

    
const char    *src = "测试";
    
char        dst[100= {0};
    size_t        src_len 
= strlen(src);
    size_t        dst_len 
= sizeof(dst);
    
const char    *in = src;
    
char        *out = dst;
    iconv_t        cd;

    
/* 将GB2312字符集转换为UTF-8字符集 */
    cd 
= iconv_open("UTF-8","GB2312" ); 
    
if ((iconv_t)-1 == cd)
    {
        
return ;
    }

    iconv(cd, 
&in&src_len, &out&dst_len);
    iconv_close(cd);


    psubele
->LinkEndChild(new TiXmlText(dst));
    pele
->LinkEndChild(psubele);
    doc.LinkEndChild(pele);

    doc.SaveFile(
"test.xml");
}
进行转换之后,就可以在IE中显示xml文件内容了。

P.S.:如果无所谓是否将xml文件显示在浏览器中,下面的两个问题就不再那么重要了。

但是,对写入的汉字进行编码转换后又会带来两个问题:
第一个,对于用utf-8编码的xml文件,如果需要在控制台中显示xml中的汉字,则又得将utf-8转为gb2312编码,否则控制台中将是一堆乱码;
第二个,对于具有如下内容的xml文件且文件实际编码也为UTF8,
<?xml version="1.0" encoding="utf-8" ?>
<ROOT>
    
<名字>测试</名字>
</ROOT>

如果用如下所示的方法来读取节点“名字”,只会输出error字样,而不是“名字”。
void find()
{
    TiXmlDocument doc;
    doc.LoadFile("test.xml");
    TiXmlElement *pEle = doc.RootElement();
    TiXmlElement *pchild = pEle->FirstChildElement("名字");

    if (!pchild)
    {
        cout 
<< "error"<<endl;
        return ;
    }
    cout<<pchild-
>Value()<<endl;
}
因为函数find中的"名字"并不是UTF8编码,"名字"的实际编码可能是ANSI编码(我也不敢确定),所以xml文件中以UTF8进行编码的“名字”和find函数中以非UTF8编码的“名字”这两个自然是不同的(对电脑而言),进而输出error。
解决办法就是将find中的汉字“名字”转为UTF8编码即可,但是要想在控制台中正确的输出pchild->Value()中所包含的UTF8编码的汉字,则又需要进行转换


还有一种方法,或者说是彻底的方法,就是直接将xml声明中的编码改为gb2312,这样一来就轻松很多,基本上上面所说的问题都不会存在了。

以上就是我个人的所遇到的问题,以及解决方法。在其中如有不正确的说法,恳请指正

另:
1. Write中用到的转换函数iconv是第三方库,并非ms或标准库自带,有需要的朋友可以Google之。
2. 要是全世界人民都用同一种语言,那该多好呀,会省了很多事,至于又会带来什么问题暂不考虑。
posted on 2010-04-08 15:07 zhaoyg 阅读(4547) 评论(0)  编辑 收藏 引用 所属分类: other

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理