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>
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 //-----------------------------------
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