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

 

转载于:https://www.cnblogs.com/anwcq/p/xerces-c.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果您的 Xerces-C 库在进行大文件校验时崩溃,可能是因为它尝试将整个文件加载到内存中进行处理,导致内存不足。为了解决这个问题,您可以使用 Xerces-C 的 SAX 接口来处理 XML 文件。SAX 接口允许您在处理 XML 文件时逐个节点处理,而不是将整个文件加载到内存中。 以下是使用 SAX 接口进行 XSD 校验的示例代码: ```c++ #include <iostream> #include <xercesc/sax/HandlerBase.hpp> #include <xercesc/parsers/XercesDOMParser.hpp> #include <xercesc/framework/LocalFileInputSource.hpp> #include <xercesc/framework/XMLValidator.hpp> #include <xercesc/util/XMLString.hpp> using namespace xercesc; class XSDValidator : public HandlerBase { public: void startElement( const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const Attributes& attrs ) { // Add your validation logic here } }; int main() { XMLPlatformUtils::Initialize(); XercesDOMParser parser; parser.setValidationScheme(XercesDOMParser::Val_Always); parser.setDoNamespaces(true); XSDValidator handler; parser.setErrorHandler(&handler); parser.setDocumentHandler(&handler); LocalFileInputSource source(XMLString::transcode("your_file.xml")); parser.parse(source); XMLPlatformUtils::Terminate(); return 0; } ``` 在上面的示例中,我们使用 Xerces-C 的 SAX 接口来处理 XML 文件。我们创建了一个名为 `XSDValidator` 的处理程序,它实现了 `HandlerBase` 接口并重写了 `startElement` 方法来添加自己的验证逻辑。在 `main` 函数中,我们创建了一个 `XercesDOMParser` 对象,并将其配置为始终进行验证。然后,我们将 `XSDValidator` 处理程序分配给 `parser` 对象,并使用 `LocalFileInputSource` 对象来指定要验证的 XML 文件。最后,我们调用 `parse` 方法来开始解析文件。 请注意,在上面的示例中,我们没有将整个文件加载到内存中。相反,我们使用 SAX 接口逐个节点处理 XML 文件,从而避免了内存不足的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值