您的位置:首页 > 编程语言 > C语言/C++

xerces C++ 解析Utf8 xml中的非UTF 8字符。修改xerces源码XMLUTF8Transcoder.cpp

2012-02-23 15:44 1036 查看
先说说遇到的问题:

要解析的xml文件是UTF8编码的,无法人工修改xml,因为xml是自动生成-自动解析的。某天遇到问题字符:<v>CD¡»¯ɽʮ¼ӗѭ1</v>,用UE打开是这样的,解析时报异常:

UTFDataFormatException,Message:invalid byte 1 () of a 1-byte sequence。单步跟踪分析,发现是在xerces第三方库中跑出的异常,原因应该是文件中含有非utf8的字符。

造成这个问题的原因:xml生成时,存在中文,且不是UTF8编码,但直接写进了UTF8 的xml文件中,因此当用UE打开时,就出现了乱码。

解决过程:

思路:找到抛出异常的位置,然后处理掉。

**想跟踪代码,发现使用的libxerces.so无法跟踪进入代码。咨询高人,安装时没有生成带debug信息的库。重新生成libxerces.so

执行脚本 ./runConfigure 时,加入参数-d 即: ./runConfigure -plinux -cgcc -xg++ -d -C--prefix=/opt/ApacheXML

**但跟踪很不顺利,放弃了。于是尝试把xerces源码加载到helloworld工程里,在eclipse里面读源码并查找。建立helloworld工程,在src右键粘贴源代码。xerces的源码编译起来太费劲了,干脆不管它,直接“Ctrl+H”,在所有工程里面搜索异常信息“UTFDataFormatException”,发现只有xerces/util目录下的XMLUTF8Transcoder.cpp中有这个异常,于是苦心钻研。

***transcodeFrom函数是把UTF 8转成Unicode,返回的是toFill,因为outPtr = toFill;所以需要修改的就是outPtr。

首先如果是ASCII(一字节,且小于等于127),则直接转换成2字节Unicode(*outPtr++ = XMLCh(*srcPtr++);)

如果是多字节,需要根据UTF8编码的规则判断是否是UTF8,然后进行转换。UTF8编码是边长的,XMLUTF8Transcoder.cpp中把UTF-8转换成Unicode的方法写的很详细,但真的是复杂啊,看的晕晕乎乎的。每个字节都要check是不是符合UTF 8编码规则,不符合就会抛异常。

***经高人指教,想到一个好办法,也就是不管哪个地方抛出异常,我们都把它catch住。本来是想还原字符内容转成utf8,但难度太大,就决定用“?”代替非法字符。

在ASCII码处理代码的下方try,在while结束之前catch,如下:

}catch(...)

{

unsigned char temp='?';

*outPtr++ = XMLCh(temp);

srcPtr++;

}

这样再生成libxerces.so就不会抛出异常了,非utf8字符被?取代。

可以程序先读一遍然后写成utf 8格式的文件保存,但没试过
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: