新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论DOM, SAX, XPath等。
    [返回] 中文XML论坛 - 专业的XML技术讨论区XML.ORG.CN讨论区 - XML技术『 DOM/SAX/XPath 』 → 如何利用Xerces C++正确处理XML文档中的中文[转帖] 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 5165 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 如何利用Xerces C++正确处理XML文档中的中文[转帖] 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     zhu_ruixian 帅哥哟,离线,有人找我吗?射手座1983-12-2
      
      
      威望:2
      等级:大二期末(Java考了96分!)
      文章:406
      积分:3471
      门派:W3CHINA.ORG
      注册:2006/3/30

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给zhu_ruixian发送一个短消息 把zhu_ruixian加入好友 查看zhu_ruixian的个人资料 搜索zhu_ruixian在『 DOM/SAX/XPath 』的所有贴子 引用回复这个贴子 回复这个贴子 查看zhu_ruixian的博客楼主
    发贴心情 如何利用Xerces C++正确处理XML文档中的中文[转帖]

    1. 背景介绍

    Apache的Xerces C++是广大c/c++程序员非常喜欢使用的XML解析器之一。主要原因是其本身是一个开放源代码的项目而且提供不同平台下的库和源代码,故深受广大c/c++程序员的欢迎。

    Xerces C++可以到以下网站下载:
    1) http://xml.apache.org/
    2) http://www.vckbase.com/tools

    2. 问题描述

    根据软件开发的要求,作者开发了一个文件特征识别软件,该软件可根据文件特有的特征识别出文件的类型。要求将文件特征保存在XML文件中。根据要求作者选择了Xerces C++作为XML解析器。但发现出了一个严重的问题:被解析的XML文件中不能包含中文,否则中文将不能正确的解析。作者研究了Xerces C++提供的例子程序,发现这些例子程序解析的结果也是错误的。只有DOMPrint程序例外。这肯定了Xerces C++本身是支持中文的。
    XML编码:

    <pdf ext="pdf" description="pdf文档">
      <magic offset="0" type="string" value="\x25\x50\x44\x46" />
    </pdf>
    SAXPrint程序解析结果:<pdf ext="pdf" description="pdf文档">
      <magic offset="0" type="string" value="\x25\x50\x44\x46"></magic>
    </pdf>
    为此,作者曾经在IBM的中文网站发现一篇文章《如何利用Xerces-C++解析包含中文字符的XML文档》并将其所描述的办法应用到程序中。但后来由于机器发生故障,硬盘上的数据全部丢失。不得不把以前做过的事重做一遍。因一时在IBM的网站上未找到上面提到的贴子,而且由于当时捡现成的没有用心研究其实现方法,故不得不仔细分析Xerces C++提供的源代码,自己动手解决中文问题。为了今后广大C++程序员碰到类似问题时不会像我一样痛苦。我也决定将自己的研究结果公布出来供大家分享。如果谁有更好的解决办法不要忘记告诉我。

    3. 原因分析

    上面的例子里,程序将“文档”两个中文字符解析成了乱码。但DOMPrint程序确能够正确解析。这表明Xerces C++对国际编码肯定是支持的。作者通过对DOMPrint和SAXPrint两个程序的比较跟踪发现问题的根本就是XMLFormatter设置的问题。由于SAX是基于事件的,大多数使用者只是简单的解析XML文档,XMLFormatter的使用比较麻烦。而DOMPrint也是通过标准的输出程序输出的屏幕上的,我们不能直接使用输出结果。
    由于XML解析器解析的字符串都是XMLCh格式的,一个字符占用一个字节,而汉字字符确要占用两个字节。故若不做适当的转换,汉字的输出结果就变成乱码了。

    4. 解决办法

    找到原因就有解决问题的方法了,明显的需要一个把解析出来的XMLCh转换成普通的字符串。这是解析,如果我们需要自己写入XML文档也有一个把普通字符串转换为XMLCh的过程。我把这两个转换过程封装在了一个名为“XMLStringTranslate”的类中。使用如下:
    void SAXMagicHandlers::startElement(const XMLCh* const name,AttributeList& attributes)
    {
     XMLStringTranslate stringTranslate("gb2312");
     string strName=stringTranslate.translate(name);//得到可包含汉字字符的普通字符串
     string strValue="pdf文档";
     XMLCh * value= stringTranslate.translate(strValue.c_str());//将普通字符串转换成XMLCh串
    }
    采用XMLStringTranslate后的实际运行结果: <pdf ext="pdf" description="pdf文档">
      <magic offset="0" type="string" value="\x25\x50\x44\x46"></magic>
    </pdf>
    特别说明:
    由于为了防止内存释放问题,将普通字符串转换成XMLCh *的translate函数返回的是类的一个成员变量,故下面的代码是不允许的: XMLCh * value1= stringTranslate.translate("测试1");
    XMLCh * value2= stringTranslate.translate("测试2");

    这样使用的结果是value1和value2的值将是一样的(因为其内存地址根本就是一样的)。正确的使用方法是通过内存拷贝或则其他方法,将value1的值保存起来或则及时使用,否则value2将影响value1的值。

    5. 结束语

    目前,许多企业已经或者正在采用Xerces C++开发XML的应用系统,相信在应用的过程中会遇到各种问题,欢迎有兴趣的朋友与我联系,共同交流。

    原文出处:http://www.vckbase.com/document/viewdoc/?id=738
    不知道以前有没有人转过,觉得不错就贴过来了。


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    为什么总是索取的人多,奉献的人少...

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/12/15 13:09:00
     
     GoogleAdSense射手座1983-12-2
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 DOM/SAX/XPath 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/5/16 0:37:59

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    47.119ms