windows下使用Xerces-C++解析XML
前景提要
最近工作中遇到收到的数据为xml格式的情况,考虑到xml解析应该是个很常用的功能,应该有开源的lib库可以使用,于是就在网上找了找,果然发现了开源库:Xerces-C++
本文目的
如题,在windows平台下使用Xerces-C++解析XML文件。
程序案例
现在有一个xml文件,要求解析出所有的节点数据给其他系统使用(本demo程序仅将数据解析到内存并打印), aaa.xml 文件如下:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <MSG>
3 <META>
4 <SNDR>FIMS</SNDR>
5 <RCVR/>
6 <SEQN>29</SEQN>
7 <DDTM>20150121194100</DDTM>
8 <TYPE>DFME</TYPE>
9 <STYP>AIRL</STYP>
10 </META>
11 <DFLT>
12 <FLID>30798</FLID>
13 <FFID>3U-8899-20150925-D</FFID>
14 <FLTK>W/Z</FLTK>
15 <AIRL>
16 <ARPT>
17 <APNO>1</APNO>
18 <APCD>CGO</APCD>
19 <FPTT>20150925194100</FPTT>
20 <FETT>20150926062203</FETT>
21 <FRTT/><FPLT/>
22 <FELT/><FRLT/>
23 <APAT>2403</APAT>
24 </ARPT>
25 <ARPT>
26 <APNO>2</APNO>
27 <APCD>SJW</APCD>
28 <FPTT/><FETT/><FRTT/>
29 <FPLT>20150925224100</FPLT>
30 <FELT/><FRLT/>
31 <APAT>2403</APAT>
32 </ARPT>
33 </AIRL>
34 </DFLT>
35 </MSG>
View Code
demo实现
读取aaa.xml文件,遍历每一个节点,若存在子节点则输出当前结点名称,若不存在子节点则输出当前结点名称和内容。
1 //----------------------------------
2
3 // xmltest.cpp : 定义控制台应用程序的入口点。
4 //
5
6 #include "stdafx.h"
7 #include <stdlib.h>
8 #include <iostream>
9
10 #include <xercesc/util/PlatformUtils.hpp>
11 #include <xercesc/dom/DOM.hpp>
12 #include <xercesc/sax/HandlerBase.hpp>
13 #include <xercesc/parsers/XercesDOMParser.hpp>
14 XERCES_CPP_NAMESPACE_USE
15
16 using namespace std;
17 void GetData(DOMElement *root) ;//自定义函数
18
19 /*const int MAXN = 2000;
20 char XMLbuf[MAXN] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><MSG><META><SNDR>SYSTEM</SNDR><TYPE>ERROR</TYPE><STYP/><DDTM>2015-09-25 14:15:25</DDTM><SEQN/></META><CONTENT><CODE>15</CODE><DESC>error,it is not on the IMF now,please retry login</DESC></CONTENT></MSG>";*/
21
22 int main()
23 {
24 /*//将字符串写入文件
25 FILE * fd = fopen("aaa.XML", "w");
26 fprintf(fd, XMLbuf);
27 fclose(fd);*/
28
29 //初始化环境
30 try{
31 XMLPlatformUtils::Initialize();
32 }
33 catch (const XMLException& toCatch) {
34 // Do your failure processing here
35 return -1;
36 }
37 //加载分析报文
38 XercesDOMParser *parser = new XercesDOMParser();
39 parser->setDoNamespaces(true); // optional
40
41 parser->setValidationScheme(XercesDOMParser::Val_Always);//设置校验计划
42 ErrorHandler* errHandler = (ErrorHandler*) new HandlerBase();
43 parser->setErrorHandler(errHandler);
44
45 //载入XML文件
46 try {
47 parser->parse("aaa.XML");
48 }
49 catch (const XMLException& toCatch) {
50 char* message = XMLString::transcode(toCatch.getMessage());
51 cout << "Exception message is: \n"
52 << message << "\n";
53 XMLString::release(&message);
54 return -2;
55 }
56 catch (const DOMException& toCatch) {
57 char* message = XMLString::transcode(toCatch.msg);
58 cout << "Exception message is: \n"
59 << message << "\n";
60 XMLString::release(&message);
61 return -3;
62 }
63 catch (...) {
64 cout << "Unexpected Exception \n";
65 return -4;
66 }
67
68 //得到文档的树型结构
69 DOMDocument *doc = parser->getDocument();
70 DOMElement *root = doc->getDocumentElement();//读取根节点
71
72 //遍历所有数据
73 GetData(root);
74
75 XMLPlatformUtils::Terminate();//释放环境
76 getchar();
77 return 0;
78 }
79
80 //获取DOM元素数据
81 void GetData(DOMElement *root) {
82 while (root != NULL) {
83 //获取子元素
84 DOMElement* child = root->getFirstElementChild();
85 //如果有子元素
86 if (child != NULL)
87 //if ((root->hasChildNodes())==true)//使用hasChildNodes()判断是否有子节点会出问题,原因不详.2015-09-28htf
88 {
89 //打印当前元素名称
90 char* name = XMLString::transcode(root->getNodeName());//child->getParentNode()->getNodeName()
91 printf("getTagName:%s\n", name);
92 XMLString::release(&name);
93
94 //获取DOM子元素数据
95 DOMElement* child = root->getFirstElementChild();
96 GetData(child);
97 }
98 //如果当前元素没有子元素
99 else {
100 //打印元素名称和值。
101 char* name = XMLString::transcode(root->getTagName());//child->getNodeName()
102 char* textContent = XMLString::transcode(root->getTextContent());
103 printf("%s:%s\n", name, textContent);
104 XMLString::release(&name);
105 XMLString::release(&textContent);
106 }
107 //指向下一个同级元素
108 root = root->getNextElementSibling();
109 }
110 }
111 //-----------------------------------
View Code
Xerces-C++: 简史
Xerces-C++ 的前身是 IBM 的 XML4C 项目。XML4C 和 XML4J 是两个并列的项目,而 XML4J 是 Xerces-J——Java 实现——的前身。IBM 将这两个项目的源代码让与 Apache 软件基金会(Apache Software Foundation),他们将其分别改名为 Xerces-C++ 和 Xerces-J。 这两个项目是 Apache XML 组的核心项目(如果看到的是“Xerces-C”而不是“Xerces-C++”,也是同一个东西,因为这个项目一开始就是用 C(译者注:原文为C++)语言编写的)。
引用 :http://www.ibm.com/developerworks/cn/xml/x-xercc/
下载和安装
下载地址 : http://xerces.apache.org/xerces-c/download.cgi
Win32 版本上的编译
主要步骤:
1.VS 2015打开xerces-c-3.1.2\projects\Win32\VC12\xerces-all\xerces-all.sln,选中XercesLib->右击->编译;
2.复制xerces-c-3.1.2\Build\Win32\VC12\Debug文件夹下的xerces-c_3_1D.dll,xerces-c_3D.lib文件到目标工程下;复制xerces-c-3.1.2下的src文件夹到目标工程下(可以不复制过来,但必须指定对应的路径);
调用动态库的配置
3.右击项目名,属性,配置“C++附加包含目录” 增加\src;配置“linker附加依赖项” 增加“xerces-c_3D.lib”;
参考:http://www.bubuko.com/infodetail-929555.html
包含头文件
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
XERCES_CPP_NAMESPACE_USE
函数介绍
初始化环境
XMLPlatformUtils::Initialize();
加载分析报文
XercesDOMParser *parser = new XercesDOMParser();
设置校验计划
parser->setDoNamespaces(true); // optional
parser->setValidationScheme(XercesDOMParser::Val_Always);
ErrorHandler* errHandler = (ErrorHandler*) new HandlerBase();
parser->setErrorHandler(errHandler);
载入XML文件
parser->parse("aaa.XML");
得到文档的树型结构
DOMDocument *doc = parser->getDocument();
DOMElement *root = doc->getDocumentElement();//读取根节点
获取子元素
DOMElement* child = root->getFirstElementChild();
获取元素名称和内容
char* name = XMLString::transcode(root->getTagName());
char* textContent = XMLString::transcode(root->getTextContent());
获取下一个同级元素
root = root->getNextElementSibling();
参考文档
官方文档:http://xerces.apache.org/xerces-c/ApacheDOMC++Binding.html
Xerces C++ 学习笔记:http://www.cppblog.com/true/archive/2007/03/15/19900.html?opt=admin
如何在VS2010中使用xerces C++:http://xzhoumin.blog.163.com/blog/static/40881136201342251923494
简单实用的Xml解析类:http://www.vckbase.com/index.php/wv/1459
c++ 使用xerces读取XML:http://www.bubuko.com/infodetail-929555.html
DOM Xerces类库使用方法:http://panpan.blog.51cto.com/489034/187272
——htfei. 2015.09.28
--------------------------------------------- 十年寒窗无人问 三更灯火五更鸣 ---------------------------------------------