以文本方式查看主题 - 中文XML论坛 - 专业的XML技术讨论区 (http://bbs.xml.org.cn/index.asp) -- 『 DTD/XML Schema 』 (http://bbs.xml.org.cn/list.asp?boardid=23) ---- 技巧:如何利用Xerces C++正确处理XML文档中的WhiteSpace (http://bbs.xml.org.cn/dispbbs.asp?boardid=23&rootid=&id=12025) |
-- 作者:anchen0617 -- 发布时间:11/13/2004 2:29:00 PM -- 技巧:如何利用Xerces C++正确处理XML文档中的WhiteSpace 1.背景介绍 Apache的Xerces C++ 和IBM的XML4C是广大C/C++编程人员非常喜欢使用的XML解析器,我比较偏好XML4C,最主要的原因是它能正确处理XML文档中的中文字符,具体可参见我以前在IBM developerWorkers China上发表的文章《如何利用Xerces-C++解析包含中文字符的XML文档》。 Xerces C++提供DOMParser和SAXParser解析XML文档,主要用途可有以下三种: 生成DOM_Document,并调用Xerces C++的API操纵内存中的XML Tree; 2.问题描述 下面以Xerces C++的DOMParser为例,描述当解析含whitespace的XML文档时存在的问题,图1是部分程序代码,图2是要解析的XML文档。 图1中的代码在创建DOMParser之后,调用了DOMParser类的setIncludeIgnorableWhitespace()方法,目的是告诉解析器不要在DOM_Document中包含whitespace,因而,根据图2所示,图1代码运行结果应为: List size = 1 List size = 3 DOMDocument doc = Parser->getDocument();
<?xml version="1.0" encoding="UTF-8"?>
图 2 test.xml
<?xml version="1.0" encoding="UTF-8"?>
图 3 去除whitespace后的test.xml 显然,利用额外的程序编程解决此问题是不明智的。Xerces C++应提供了相应的机制来解决它。我用google搜索了这方面的信息,发现还是有许多人遇到了此类问题,尽管IBM论坛上有人提出了解决思路,但是,还不够完整,我在研究Xerces C++的相关资料和代码解决此问题后认为,如何利用Xerces C++正确处理xml文档中的whitespace问题需要有较详细的解释和解决方法,权当是抛砖引玉吧,希望能为Xerces C++或XML4C的普及应用有所帮助。 3.原因分析 根据void DOMParser::setIncludeIgnorableWhitespace (const bool include ) 的文档说明,Parser是否包含whitespace的设置仅在Parser对XML文档进行有效性验证处理时有效。因而,图2中的test.xml只能是格式良好的XML文档,由于它没有相应的schema定义,所以,DOMParser无法对此文档进行有效性验证,缺省认为whitespace是DOM_Document的子节点,类型是DOM_Text。 那么,为test.xml提供schema之后,图1的运行结果是否正确呢?答案是不正确的,DOMParser还需要调用下列的API来设置其它选项。 方法名 方法说明 因而,通过设置DOMParser的几个选项并提供test.xml的schema就应该能解决whitespace的问题。 4. 解决方法 基于上面的分析,我们首先需要为test.xml提供schema定义,这是解决此问题的第一步,也是必须的,如果不提供schema定义而想完成xml文档的紧缩处理,则需要程序员额外增加实现代码;或者使用SAXParser,在实现ContentHandler::ignorableWhitespace(const XMLCh* const chars, const unsigned int length)的纯虚方法中特殊处理,不为whitespace生成DOM_Text节点。但我这里不推荐此种处理方法,XML文档的有效性验证在许多应用系统中是必须的。 Test.xml的schema文件定义见Xerces C++包中的文件:<xerces C++安装路径>\data\personal.xsd,相应地,test.xml中需要标注shema,详细见:<xerces C++安装路径>\data\personal-schema.xml文件,这里在图5中给出shema的声明部分。 在上述步骤完成后,修改图1的程序代码,设置Parser支持XML文档的有效性验证,具体见图6。
图 5 schema的声明
XMLPlatformUtils::Initialize(); DOMDocument doc = Parser->getDocument();
图 6 最终程序代码 需要说明以下几点: XML文档和shema定义中都用到了名域,如图5中的xsi,schema定义中的xsd:element等等,所以,parser一定要设置名域的支持(调用setDoNamespaces(true)),否则,parser在解析xml的过程中会抛出异常。 目前,许多企业已经或者正在采用Xerces C++开发XML的应用系统,相信在应用的过程中会遇到各种问题,欢迎有兴趣的朋友与我联系,共同交流。
|
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
31.250ms |