(写次笔记的目的除了对知识点进行笔记外,还有就是希望能够帮助和我一样有遇到类似问题的朋友。)
刚接触tinyxml时,对于编码问题没怎么注意,但就是这个没有被我注意的问题,在暗地里向我放“黑枪”,耗了我不少时间。
现在就来说说我遇到的问题,以及我的解决方法。
如有不对的地方, 恳请指正 ,小弟在这先谢谢了。
对于如下代码,
生成的test.xml文件如果直接用IE查看,则会提示说遇见无效字符。之所以这样是因为,当文件进行保存时,文件的实际编码是ansi,而在ie进行解读时会根据声明中指定的编码utf-8来进行解释,对于英文字母来说utf-8和ansi是兼容的,但因为其中有汉字,所以用utf-8来解释编码为ansi的汉字就会出现乱码的问题,从而使得ie提示说遇见无效字符。
而解决的方法是,将写入的中文字符串转为utf-8编码
P.S.:如果无所谓是否将xml文件显示在浏览器中,下面的两个问题就不再那么重要了。
但是,对写入的汉字进行编码转换后又会带来两个问题:
第一个,对于用utf-8编码的xml文件,如果需要在控制台中显示xml中的汉字,则又得将utf-8转为gb2312编码,否则控制台中将是一堆乱码;
第二个,对于具有如下内容的xml文件且文件实际编码也为UTF8,
如果用如下所示的方法来读取节点“名字”,只会输出error字样,而不是“名字”。
解决办法就是将find中的汉字“名字”转为UTF8编码即可,但是要想在控制台中正确的输出pchild->Value()中所包含的UTF8编码的汉字,则又需要进行转换 。
还有一种方法,或者说是彻底的方法,就是直接将xml声明中的编码改为gb2312,这样一来就轻松很多,基本上上面所说的问题都不会存在了。
以上就是我个人的所遇到的问题,以及解决方法。在其中如有不正确的说法, 恳请指正 。
另:
1. Write中用到的转换函数iconv是第三方库,并非ms或标准库自带,有需要的朋友可以Google之。
2. 要是全世界人民都用同一种语言,那该多好呀,会省了很多事,至于又会带来什么问题暂不考虑
刚接触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 " );
}
{
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文件内容了。
{
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 " );
}
P.S.:如果无所谓是否将xml文件显示在浏览器中,下面的两个问题就不再那么重要了。
但是,对写入的汉字进行编码转换后又会带来两个问题:
第一个,对于用utf-8编码的xml文件,如果需要在控制台中显示xml中的汉字,则又得将utf-8转为gb2312编码,否则控制台中将是一堆乱码;
第二个,对于具有如下内容的xml文件且文件实际编码也为UTF8,
<?
xml version="1.0" encoding="utf-8"
?>
< ROOT >
< 名字 > 测试 </ 名字 >
</ ROOT >
< 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。
{
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编码即可,但是要想在控制台中正确的输出pchild->Value()中所包含的UTF8编码的汉字,则又需要进行转换 。
还有一种方法,或者说是彻底的方法,就是直接将xml声明中的编码改为gb2312,这样一来就轻松很多,基本上上面所说的问题都不会存在了。
以上就是我个人的所遇到的问题,以及解决方法。在其中如有不正确的说法, 恳请指正 。
另:
1. Write中用到的转换函数iconv是第三方库,并非ms或标准库自带,有需要的朋友可以Google之。
2. 要是全世界人民都用同一种语言,那该多好呀,会省了很多事,至于又会带来什么问题暂不考虑