Technical Blog Post
Abstract
使用XML Toolkit for IBM i 解析XML文件
Body
XML Toolkit for IBM i是IBM i上的License Program,用于提供在IBM i 上的XML解析及XSL转换的功能。最新版本5733XT2提供了支持C++的XML解析器——XML4C,以及支持Procedural Language(如ILE C, RPG, COBOL)的XML解析器——XML4PR。本文将以RPG语言为例,简要介绍使用XML Toolkit for IBM i对XML文件进行解析的方法。
(一)XML Toolkit for IBM i的各个组件
在安装完5733XT2产品的Option6、7之后,通过WRKLIB QXML563V6命令查看安装完成后的组件。
H——头文件目录
QCBLLESRC ——COBOL语言版本的范例代码目录
QCLSRC——编译范例代码的CL语言代码
QCSRC——C语言版本的范例代码目录
QRPGLESRC——RPG语言版本的范例代码目录
另外在IFS路径/qibm/proddata/xmltoolkitv6/xml5_6_3/samples/之下,放置了所有C++语言的范例代码。路径/qibm/proddata/xmltoolkitv6/xml5_6_3/doc/之下,拥有详细的产品说明文档。
(二)编译、运行范例代码
以RPG语言为例,使用如下命令将范例代码编译成可执行程序:
CRTCLPGM [CLLIB]/CRTXMLRPG QXML563V6/QCLSRC
CALL [CLLIB]/CRTXMLRPG [RPGLIB]
其中[CLLIB]需要替换成放置编译后的CL程序的目录, [RPGLIB]需要替换成保存这些编译完成后的RPG程序的目录名。
这里以新创建的XMLRPG为例,RPG目录设置为XMLPR563V6。依次输入
CRTLIB XMLRPG
CRTCLPGM XMLRPG/CRTXMLRPG QXML563V6/QCLSRC
CALL XMLRPG/CRTXMLRPG XMLPR563V6
三条命令。其中第三条命令需要执行较长时间,因为涉及到大量代码的编译。全部完成后,显示如下:
CALL XMLPR563V6/DOMCount ('/qibm/proddata/xmltoolkitv6/xml5_6_3/samples/data/personal.xml')
程序运行成功,解析完XML文件的结果显示该XML文件中包含有37个元素。
同样我们可选用基于事件驱动SAX解析器来进行解析:
CALL XMLPR563V6/SAXCount ('/qibm/proddata/xmltoolkitv4/xml5_6_3/samples/data/personal.xml')
所有的范例程序包括CreateDoc、CreateXML、DOMPrint、PParse、SAXCount、DOMCount、MEMParse、Redirect、SAXPrint、SAX2Count、SAX2Print、SetRmvAttr、XMLCalc、XMLCalcMem。在'/qibm/proddata/xmltoolkitv4/xml5_6_3/doc/xml4pr/buildrpg.html'文件中有对各个范例程序的作用的介绍。
(三)使用RPG解析XML文件
对于使用DOM解析器解析XML文件的程序,至少应该包含下面几个基本组成部分。
(1)初始化环境
(2)创建解析器对象
(3)获取DOM对象
(4)操纵DOM树中的元素
(5)销毁DOM对象
(6)销毁解析器对象
(7)清理环境并退出
下面我们以一个简单的例子来说明基于DOM解析器的代码结构。代码中的XmlFilePath变量需要设置为待解析的XML文件的实际路径。
/COPY QXML563V6/QRPGLESRC,QXML4PR563
DEnvData@ S * INZ(%ADDR(Qxml_DomExcData))
DPEnvData@ S * INZ(%ADDR(Qxml_SaxExcData))
DDomParse@ S *
DDomDoc@ S *
* Initialize XML environment
C CALLP QxmlInit(EnvData@)
C EVAL DomParse@ = QxmlXercesDOMParser_new(PEnvData@)
C CALLP QxmlXercesDOMParser_parse_SystemId(
C DomParse@:
C XmlFilePath@:
C Qxml_CCSID37:
C 0)
C EVAL DomDoc@ = QxmlXercesDOMParser_getDocument(DomParse@)
* DOM elements manipulations...
* Cleanup any object allocations
C CALLP QxmlDOMDocument_delete(DomDoc@)
C CALLP QxmlXercesDOMParser_delete(DomParse@)
* Call XML termination
C CALLP QxmlTerm
这段代码首先是初始化XML解析器的环境,使用的是QxmlInit函数。然后使用了QxmlXercesDOMParser_new函数创建一个解析器对象DomParse。并将需要处理的XML文件名设置好。此后可以为这个解析器设置各类属性,例如validation、namespace,、schema选项等等。
在DOMCOUNT这个程序中,需要根据解析后的XML文件内容在内存中创建一个DOM树。这里就用到了QxmlXercesDOMParser_getDocument函数来创建DOM树。得到DOM树后便可以对树中的元素进行各类操作了。
在操作完毕后,需要按照与创建过程相反的顺序依次销毁创建的对象。首先销毁内存中创建的DOM树,然后是解析器,最后通过QxmlTerm函数终结程序。
对于SAX解析器,其程序结构大体上与DOM解析器类似。同样是由QxmlInit函数初始化环境,然后创建解析器进行解析,解析完毕后清理资源,最后使用QxmlTerm结束。但是因为SAX解析器是基于事件驱动的模型,因此不存在DOM树的内存结构。相对应的,SAX解析器依赖于不同事件的各个回调函数工作,因此SAX程序的功能主体往往是由大量的回调函数组成。一般而言这些回调函数的注册是在创建解析器后进行的。 * Initialize XML environment C CALLP QxmlInit(ENVDATA@) * Create a SAX Parser object, set various input options C EVAL SAXParse@ = QxmlSAXPARSER_new * Create a document and error handler and register with parser C EVAL DOCHNDLR@ = QxmlDocumentHandler_new C EVAL ERRHNDLR@ = QxmlErrorHandler_new C CALLP QxmlSAXParser_setDocumentHandler(SAXParse@:DOCHNDLR@) C CALLP QxmlSAXParser_setErrorHandler(SAXParse@:ERRHNDLR@) * Register the callback routines based on specific SAX Document * and Error handler events (such as STARTDOUCMENT, CHARACTERS, etc) C CALLP QxmlDocumentHandler_setCallback() …… * Call parser providing XML file name C CALLP QxmlSAXParser_parse_systemid(SAXParse@:XmlFile@:Qxml_CCSID37:0) * Cleanup any object allocations C CALLP QxmlDocumentHandler_delete(DOCHNDLR@) C CALLP QxmlErrorHandler_delete(ERRHNDLR@) C CALLP QxmlSAXPARSER_delete(SAXParse@) C CALLP QxmlTerm * Many Call back functions …… 通过以上两个程序片段,我们可以看到使用RPG语言解析XML文件的通用代码结构。在解析器的选择上,如果解析的XML文件体积较小,并且需要随机访问某个不特定元素的属性,那么DOM解析器是一个较好的选择。而如果解析的XML文件过大,那么基于事件驱动的SAX解析器将会更具优势。 *除了上面两个简单的程序之外,我们还可以通过STRPDM命令查看附带的大量示例程序的源代码。
UID
ibm11145260