将TinyXml快速入门的接口面向对象化(转载)
作者:朱金灿
来源:http://www.cnblogs.com/clever101
在TinyXml快速入门的系列文章中(详情见本博客),我只是将tinyxml类库解析xml文件的类封装为API接口。这次我决定将这些API接口对象化,并结合自定义的数据结构解析xml文件。
具体是新建一个CXmlParse类,头文件声明如下:
#include <string>
#include <vector>
#include <map>
#include "..\tinyxml\tinyxml.h"
#include "BaseStruct.h"
using std::string;
using std::vector;
using std::map; /*! \struct MyAppInfo XmlParse.h
* \brief 程序信息结构体.
*
* 包含了程序名、公司名和公司网址
*/
struct MyAppInfo
{
MyAppInfo()
{
m_strAppName = _T("");
m_strCompanyName = _T("") ;
m_strUrl = _T("") ;
} string m_strAppName;
string m_strCompanyName;
string m_strUrl;
};
/*! \class CXmlParse XmlParse.h
* \brief xml文件解析类
*
* 实现对xml文件的查询、修改和删除节点操作
* \author 朱金灿.
* \version 0.1
* \date 2010.03.28.
*/
class CXmlParse
{
public:
CXmlParse(void);
~CXmlParse(void); public: /*!
* \brief 打开xml文件。
*
* \param [in]XmlFile xml文件全路径。
* \return 是否成功。true为成功,false表示失败。
*/
bool OpenXml(const string& XmlFile); /*!
* \brief 在控制台上打印xml文件。
*
* \return 无。
*/
void PaintXml(); /*!
* \brief 获取xml文件的声明。
*
* \param strVersion [in][out]Version属性值
* \param strStandalone [in][out]Standalone属性值
* \param strEncoding [in][out]Encoding属性值
* \return 是否成功。true为成功,false表示失败。
*/
bool GetXmlDeclare(string &strVersion,string &strStandalone,string &strEncoding); /*!
* \brief 通过节点查询。
*
* \param strNodeName [in]要查询的节点名
* \param strText [in][out]查询的结果节点文本
* \return 是否找到。true为成功找到,false表示没有找到。
*/
bool QueryNode_Text(const string& strNodeName,string &strText); /*!
* \brief 通过节点查询。
*
* \param strNodeName [in]要查询的节点名
* \param AttMap [in][out]查询的结果属性值,这是一个map,前一个为属性名,后一个为属性值
* \return 是否成功。true为成功,false表示失败。
*/
bool QueryNode_Attribute(const string& strNodeName,map<string,string> &AttMap); /*!
* \brief 删除指定节点的值。
*
* \param strNodeName [in]指定的节点名。
* \return 是否成功。true为成功,false表示失败。
*/
bool DelNode(const string& strNodeName); /*!
* \brief 修改指定节点的文本。
*
* \param strNodeName [in]指定的节点名。
* \param strText [in]重新设定的文本的值
* \return 是否成功。true为成功,false表示失败。
*/
bool ModifyNode_Text(const string& strNodeName,const string& strText); /*!
* \brief 修改指定节点的属性。
*
* \param [in]strNodeName 指定的节点名。
* \param [in]AttMap 重新设定的属性值,这是一个map,前一个为属性名,后一个为属性值
* \return 是否成功。true为成功,false表示失败。
*/
bool ModifyNode_Attribute(const string& strNodeName,
const map<string,string>& AttMap); /*!
* \brief 修改指定节点的属性。
*
* \param [in]strNodeName 指定的节点名。
* \param [in]strAttValue 指定的节点的其中一个属性值。
* \param [in]AttMap 重新设定的属性值,这是一个map,前一个为属性名,后一个为属性值
* \return 是否成功。true为成功,false表示失败。
*/
bool ModifyNode_Attribute2(string strNodeName,string strAttValue,
const map<string,string> &AttMap);public: /*! * \brief 获取应用程序信息。 * * \param [in][out]Info 指定的节点名。 * \return 是否成功。true为成功,false表示失败。 */ bool GetAppInfo(MyAppInfo& Info);private: /*! * \brief 通过根节点和节点名获取节点指针。 * * \param pRootEle [in]xml文件的待检查的节点。 * \param strNodeName [in]要查询的节点名。 * \param Node [in][out]需要查询的节点指针。 * \return 是否找到。true为找到相应节点指针,false表示没有找到相应节点指针。 */ bool GetNodePointerByName(TiXmlElement* pRootEle,const string &strNodeName,TiXmlElement* &Node); /*! * \brief 通过根节点和节点名以及节点的一个属性值获取节点指针。 * * \param pRootEle [in]xml文件的待检查的节点。 * \param strNodeName [in]要查询的节点名 * \param strNodeName [in]要查询的节点的一个属性值 * \param Node [in][out]需要查询的节点指针 * \return 是否找到。true为找到相应节点指针,false表示没有找到相应节点指针。 */ bool GetNodePointerByName_Attribute(TiXmlElement* pRootEle, const string &strNodeName, const string &strAttributeValue, TiXmlElement* &Node);protected: /** * \brief 实际操作xml文件的类。 */ TiXmlDocument *m_pDoc; /** * \brief xml文件全路径。 */ string m_strXmlFile;};
实现文件的代码如下:
#include <assert.h>
#include "XmlParse.h" CXmlParse::CXmlParse(void)
{
m_pDoc = NULL;
m_strXmlFile = _T("");
} CXmlParse::~CXmlParse(void)
{
delete m_pDoc;
} bool CXmlParse::OpenXml(const string& XmlFile)
{
if (NULL!=m_pDoc)
{
delete m_pDoc;
m_pDoc = NULL;
} m_pDoc = new TiXmlDocument(); if (NULL==m_pDoc)
{
return false;
} m_pDoc->LoadFile(XmlFile);
m_strXmlFile = XmlFile;
return true;
} void CXmlParse::PaintXml()
{
assert(NULL!=m_pDoc);
m_pDoc->Print();
} bool CXmlParse::GetXmlDeclare(string &strVersion,string &strStandalone,string &strEncoding)
{
assert(NULL!=m_pDoc);
// 找到第一个节点
TiXmlNode* pXmlFirst = m_pDoc->FirstChild();
if (NULL != pXmlFirst)
{
TiXmlDeclaration* pXmlDec = pXmlFirst->ToDeclaration();
if (NULL != pXmlDec)
{
// 获取各种信息
strVersion = pXmlDec->Version();
strStandalone = pXmlDec->Standalone();
strEncoding = pXmlDec->Encoding();
}
}
return true;
} bool CXmlParse::GetNodePointerByName(TiXmlElement* pRootEle,const string &strNodeName,TiXmlElement* &Node)
{
assert(NULL!=pRootEle);
if (strNodeName==pRootEle->Value())
{
Node = pRootEle;
return true;
} TiXmlElement* pEle = pRootEle;
for (pEle = pRootEle->FirstChildElement();pEle;pEle = pEle->NextSiblingElement())
{
//递归处理子节点
if(GetNodePointerByName(pEle,strNodeName,Node))
return true;
} return false;
} bool CXmlParse::GetNodePointerByName_Attribute(TiXmlElement* pRootEle,
const string &strNodeName,
const string &strAttributeValue,
TiXmlElement* &Node)
{
assert(NULL!=pRootEle); // 假如等于根节点名,就退出 if (strNodeName==pRootEle->Value()) { TiXmlAttribute* pAttr = NULL; for (pAttr = pRootEle->FirstAttribute(); pAttr; pAttr = pAttr->Next()) { std::string strAttValue = pAttr->Value(); if (strAttributeValue==strAttValue) { Node = pRootEle; } } } TiXmlElement* pEle = pRootEle; for (pEle = pRootEle->FirstChildElement(); pEle; pEle = pEle->NextSiblingElement()) { //递归处理子节点 if(GetNodePointerByName_Attribute(pEle,strNodeName,strAttributeValue,Node)) return true; } return false;} bool CXmlParse::QueryNode_Text(const string& strNodeName,string &strText) { assert(NULL!=m_pDoc); TiXmlElement *pRootEle = m_pDoc->RootElement(); if (NULL==pRootEle) { return false; } TiXmlElement *pNode = NULL; GetNodePointerByName(pRootEle,strNodeName,pNode); if (NULL!=pNode) { const char* psz = pNode->GetText(); if (NULL==psz) { strText = _T(""); } else { strText = psz; } return true; } else { return false; } } bool CXmlParse::QueryNode_Attribute(const string& strNodeName,map<string,string> &AttMap) { assert(NULL!=m_pDoc); typedef std::pair <std::string,std::string> String_Pair; TiXmlElement *pRootEle = m_pDoc->RootElement(); if (NULL==pRootEle) { return false; } TiXmlElement *pNode = NULL; GetNodePointerByName(pRootEle,strNodeName,pNode); if (NULL!=pNode) { TiXmlAttribute* pAttr = NULL; for (pAttr = pNode->FirstAttribute(); pAttr; pAttr = pAttr->Next()) { std::string strAttName = pAttr->Name(); std::string strAttValue = pAttr->Value(); AttMap.insert(String_Pair(strAttName,strAttValue)); } return true; } else { return false; }} bool CXmlParse::DelNode(const string& strNodeName) { assert(NULL!=m_pDoc); TiXmlElement *pRootEle = m_pDoc->RootElement(); if (NULL==pRootEle) { return false; } TiXmlElement *pNode = NULL; GetNodePointerByName(pRootEle,strNodeName,pNode); // 假如要删除的是根节点 if (pRootEle==pNode) { if(m_pDoc->RemoveChild(pRootEle)) { m_pDoc->SaveFile(m_strXmlFile); return true; } else return false; } // 假如要删除的是其它节点 if (NULL!=pNode) { TiXmlNode *pParNode = pNode->Parent(); if (NULL==pParNode) { return false; } TiXmlElement* pParentEle = pParNode->ToElement(); if (NULL!=pParentEle) { if(pParentEle->RemoveChild(pNode)) m_pDoc->SaveFile(m_strXmlFile); else return false; } } else { return false; } return false; } bool CXmlParse::ModifyNode_Text(const string& strNodeName,const string& strText) { assert(NULL!=m_pDoc); TiXmlElement *pRootEle = m_pDoc->RootElement(); if (NULL==pRootEle) { return false; } TiXmlElement *pNode = NULL; GetNodePointerByName(pRootEle,strNodeName,pNode); if (NULL!=pNode) { pNode->Clear(); // 首先清除所有文本 // 然后插入文本,保存文件 TiXmlText *pValue = new TiXmlText(strText); pNode->LinkEndChild(pValue); m_pDoc->SaveFile(m_strXmlFile); return true; } else return false; } bool CXmlParse::ModifyNode_Attribute(const string& strNodeName, const map<string,string>& AttMap) { assert(NULL!=m_pDoc); typedef std::pair <std::string,std::string> String_Pair; TiXmlElement *pRootEle = m_pDoc->RootElement(); if (NULL==pRootEle) { return false; } TiXmlElement *pNode = NULL; GetNodePointerByName(pRootEle,strNodeName,pNode); if (NULL!=pNode) { TiXmlAttribute* pAttr = NULL; std::string strAttName = _T(""); std::string strAttValue = _T(""); for (pAttr = pNode->FirstAttribute(); pAttr; pAttr = pAttr->Next()) { strAttName = pAttr->Name(); std::map<std::string,std::string>::const_iterator iter; for (iter=AttMap.begin();iter!=AttMap.end();iter++) { if (strAttName==iter->first) { pAttr->SetValue(iter->second); } } } m_pDoc->SaveFile(m_strXmlFile); return true; } else { return false; } } bool CXmlParse::ModifyNode_Attribute2(string strNodeName,string strAttValue, const map<string,string> &AttMap) { assert(NULL!=m_pDoc); typedef std::pair <std::string,std::string> String_Pair; TiXmlElement *pRootEle = m_pDoc->RootElement(); if (NULL==pRootEle) { return false; } TiXmlElement *pNode = NULL; GetNodePointerByName_Attribute(pRootEle,strNodeName,strAttValue,pNode); if (NULL!=pNode) { TiXmlAttribute* pAttr = NULL; std::string strAttName = _T(""); std::string strAttValue = _T(""); for (pAttr = pNode->FirstAttribute(); pAttr; pAttr = pAttr->Next()) { strAttName = pAttr->Name(); std::map<std::string,std::string>::const_iterator iter; for (iter=AttMap.begin();iter!=AttMap.end();iter++) { if (strAttName==iter->first) { pAttr->SetValue(iter->second); } } } m_pDoc->SaveFile(m_strXmlFile); return true; } else { return false; } } bool CXmlParse::GetAppInfo(MyAppInfo& Info) { map<string,string> AttMap; bool bSucc = QueryNode_Attribute(string(_T("Framework")),AttMap); std::map<std::string,std::string>::iterator iter; for (iter=AttMap.begin();iter!=AttMap.end();iter++) { if (string(_T("AppName"))==iter->first) { Info.m_strAppName = iter->second; } else if (string(_T("company"))==iter->first) { Info.m_strCompanyName = iter->second; } else if (string(_T("url"))==iter->first) { Info.m_strUrl = iter->second; } } return bSucc; }
注意,上面的CXmlParse类在封装API接口操作的同时,结合一个用户自定义结构MyAppInfo来解析xml文件的内容。
简单测试:
Xml文件的内容如下:
<?xml version="1.0" encoding="GB2312" standalone="no" ?>
<BoostBind>
<Framework AppName="boost库测试程序 V1.0" company="BigHardware company" url="http:www.BigHardware.com" />
<UIDescription>
<AppMenuBar valid="1" caption="文件(F)">
<MenuItem valid="1" identity="file_new" caption="新建" />
<MenuItem valid="1" identity="file_open" caption="打开" />
</AppMenuBar>
<AppMenuBar valid="1" caption="编辑(E)">
<MenuItem valid="1" identity="edit_copy" caption="拷贝" />
<MenuItem valid="1" identity="edit_paste" caption="粘贴" />
</AppMenuBar>
</UIDescription>
</BoostBind>
现在我们要获取Framework节点的信息,将其填充到MyAppInfo类型的变量中,具体代码如下:
CXmlParse SysSetting;
SysSetting.OpenXml(string(_T("F:\\MyTest\\MyTest\\src\\outdir\\debug\\SysConfig.xml")));
MyAppInfo Info;
SysSetting.GetAppInfo(Info);
将TinyXml快速入门的接口面向对象化(转载)的更多相关文章
- TinyXml 快速入门(三)
在<TinyXml 快速入门(二)>介绍使用tinyxml库获取xml文件声明,查询指定节点.删除指定节点的做法.在本文中继续介绍修改指定节点和增加节点的做法. 修改节点其实和查询指定节点 ...
- TinyXml快速入门(二)
在<TinyXml快速入门(一)>中我介绍了使用TinyXml库如何创建和打印xml文件,下面我介绍使用tinyxml库对xml文件进行一系列的操作,包括获取xml文件声明,查询指定节点. ...
- TinyXml快速入门(一)
对于xml文件,目前的工作只是集中在配置文件和作为简单的信息文件来用,因此我不太喜欢使用msxml这种重量级的xml解析器,特别是使用msxml解析xml涉及到复杂的com类型转换,更是令人感觉繁琐. ...
- Java快速入门-02-基础篇
Java快速入门-02-基础篇 上一篇应该已经让0基础的人对 Java 有了一些了解,接一篇更进一步 使用 Eclipse 快捷键 这个老师一般都经常提,但是自己不容易记住,慢慢熟练 快捷键 快捷键作 ...
- Java快速入门-01-基础篇
Java快速入门-01-基础篇 如果基础不好或者想学的很细,请参看:菜鸟教程-JAVA 本笔记适合快速学习,文章后面也会包含一些常见面试问题,记住快捷键操作,一些内容我就不转载了,直接附上链接,嘻嘻 ...
- 学习Go语言(二)快速入门
作为一名学习过多种编程语言的“老码农”,学习一门新的语言不能像“新手”一样,要快速入门. 无论面向过程,还是面向对象的编程语言:静态语言,动态语言,一般都包括: 标识符.变量(常量).运算符.表达式. ...
- 3.1_springboot2.x检索之elasticsearch安装&快速入门
1.elasticsearch简介&安装 1.1.1.elasticsearch介绍 我们的应用经常需要添加检索功能,开源的 ElasticSearch 是目前全文搜索引擎的首选.他可以快 ...
- Spark快速入门 - Spark 1.6.0
Spark快速入门 - Spark 1.6.0 转载请注明出处:http://www.cnblogs.com/BYRans/ 快速入门(Quick Start) 本文简单介绍了Spark的使用方式.首 ...
- 夺命雷公狗---微信开发54----微信js-sdk接口开发(1)之快速入门
js-sdk基本介绍 除去服务号的九大接口外,微信提供了JS-SDK接口,所谓JS-SDK接口也就是在网页中使用javascript来更改网页设置, (比如隐藏右上角的菜单)获取用户状态(比如地理位置 ...
随机推荐
- 598. Range Addition II
Given an m * n matrixMinitialized with all0's and several update operations. Operations are represen ...
- 自定义bootstrap样式-9行样式自定义漂亮大气bootstrap导航栏
有人说前端发展太快,框架太多,各有所需,各有所长.看看这幅图,估计都知道这些框架,但是大部分公司中实际要用到的也就那么几个. 发展再快,框架再多.还是得回到原点,不就是Html+Css+JavaScr ...
- python 将文件夹内的图片转换成PDF
import os import stringfrom PIL import Imagefrom reportlab.lib.pagesizes import A4, landscapefrom re ...
- 使用 PyCharm 添加 第三方 依赖库
背景 最近开始搞python, 需要帮助算法同事一起调试程序,在本地安装python以后使用 pip 来安装第三方库. 但是算法同事一直使用的是PyCharm 这个IDE,所以需要与他一起调试的时候也 ...
- BeanShell断言(一)
在beanShell中直接可以调用的变量,无需加前缀. 1.log 打印日志 log.info(“在控制台打印日志”); 2.SampleResult 获取SampleResult对象,可以通过这个对 ...
- 关于模拟登陆微博(PC)
微博模拟登陆 1.基类对象的方法建立一个类__init__初始化方法,接收username和password. class launcher(): def __init__(self, usernam ...
- python匿名函数
文章导读: 以前自己一直没搞明白Python中的匿名函数,现在拿这个问题基本上搞明白了,拿自己的理解整成一篇文章,附带大量例子,让其更加好理解. 在编程语言中,函数的应用: 1. 代码块重复,这时候必 ...
- PHP进阶,使用交互模式进行快速测试实验?
额,那啥,PHP很强,大家都知道哈.不过呢,在搞PHP里的人中,自然也要分高下的.当然了,我更喜欢用好玩来形容了. 什么叫做快速开发?我觉得,快就得快到随手写几个字,就能让代码跑起来!那么,PHP能做 ...
- OLAP与数据仓库------《Designing Data-Intensive Applications》读书笔记4
由于第三章的内容比较多,这里我们拆分成两篇读书笔记来记录.上一章我们聊了聊如何数据库是如何实现存储和检索的,今天这篇我们继续来看看OLTP与OLAP存储引擎的区别与联系. 1.OLTP与OLAP 联机 ...
- VMware仅主机模式虚拟机无法ping通物理机
问题描述 在VMware Workstation中新建了一个虚拟机CentOS7,网络适配器选择的是"仅主机模式",结果,物理机ping不通虚拟机,虚拟机也ping不通物理机. 原 ...