windows下使用xerces -c解析XML


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM