您的位置:首页 > 其它

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

2010-03-28 15:11 471 查看
作者:朱金灿

来源: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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: