将TinyXml快速入门的接口面向对象化

作者:朱金灿
来源:http://blog.csdn.net/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);














  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值