作者:朱金灿

来源: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快速入门的接口面向对象化(转载)的更多相关文章

  1. TinyXml 快速入门(三)

    在<TinyXml 快速入门(二)>介绍使用tinyxml库获取xml文件声明,查询指定节点.删除指定节点的做法.在本文中继续介绍修改指定节点和增加节点的做法. 修改节点其实和查询指定节点 ...

  2. TinyXml快速入门(二)

    在<TinyXml快速入门(一)>中我介绍了使用TinyXml库如何创建和打印xml文件,下面我介绍使用tinyxml库对xml文件进行一系列的操作,包括获取xml文件声明,查询指定节点. ...

  3. TinyXml快速入门(一)

    对于xml文件,目前的工作只是集中在配置文件和作为简单的信息文件来用,因此我不太喜欢使用msxml这种重量级的xml解析器,特别是使用msxml解析xml涉及到复杂的com类型转换,更是令人感觉繁琐. ...

  4. Java快速入门-02-基础篇

    Java快速入门-02-基础篇 上一篇应该已经让0基础的人对 Java 有了一些了解,接一篇更进一步 使用 Eclipse 快捷键 这个老师一般都经常提,但是自己不容易记住,慢慢熟练 快捷键 快捷键作 ...

  5. Java快速入门-01-基础篇

    Java快速入门-01-基础篇 如果基础不好或者想学的很细,请参看:菜鸟教程-JAVA 本笔记适合快速学习,文章后面也会包含一些常见面试问题,记住快捷键操作,一些内容我就不转载了,直接附上链接,嘻嘻 ...

  6. 学习Go语言(二)快速入门

    作为一名学习过多种编程语言的“老码农”,学习一门新的语言不能像“新手”一样,要快速入门. 无论面向过程,还是面向对象的编程语言:静态语言,动态语言,一般都包括: 标识符.变量(常量).运算符.表达式. ...

  7. 3.1_springboot2.x检索之elasticsearch安装&快速入门

    1.elasticsearch简介&安装 1.1.1.elasticsearch介绍 ​ 我们的应用经常需要添加检索功能,开源的 ElasticSearch 是目前全文搜索引擎的首选.他可以快 ...

  8. Spark快速入门 - Spark 1.6.0

    Spark快速入门 - Spark 1.6.0 转载请注明出处:http://www.cnblogs.com/BYRans/ 快速入门(Quick Start) 本文简单介绍了Spark的使用方式.首 ...

  9. 夺命雷公狗---微信开发54----微信js-sdk接口开发(1)之快速入门

    js-sdk基本介绍 除去服务号的九大接口外,微信提供了JS-SDK接口,所谓JS-SDK接口也就是在网页中使用javascript来更改网页设置, (比如隐藏右上角的菜单)获取用户状态(比如地理位置 ...

随机推荐

  1. 598. Range Addition II

    Given an m * n matrixMinitialized with all0's and several update operations. Operations are represen ...

  2. 自定义bootstrap样式-9行样式自定义漂亮大气bootstrap导航栏

    有人说前端发展太快,框架太多,各有所需,各有所长.看看这幅图,估计都知道这些框架,但是大部分公司中实际要用到的也就那么几个. 发展再快,框架再多.还是得回到原点,不就是Html+Css+JavaScr ...

  3. python 将文件夹内的图片转换成PDF

    import os import stringfrom PIL import Imagefrom reportlab.lib.pagesizes import A4, landscapefrom re ...

  4. 使用 PyCharm 添加 第三方 依赖库

    背景 最近开始搞python, 需要帮助算法同事一起调试程序,在本地安装python以后使用 pip 来安装第三方库. 但是算法同事一直使用的是PyCharm 这个IDE,所以需要与他一起调试的时候也 ...

  5. BeanShell断言(一)

    在beanShell中直接可以调用的变量,无需加前缀. 1.log 打印日志 log.info(“在控制台打印日志”); 2.SampleResult 获取SampleResult对象,可以通过这个对 ...

  6. 关于模拟登陆微博(PC)

    微博模拟登陆 1.基类对象的方法建立一个类__init__初始化方法,接收username和password. class launcher(): def __init__(self, usernam ...

  7. python匿名函数

    文章导读: 以前自己一直没搞明白Python中的匿名函数,现在拿这个问题基本上搞明白了,拿自己的理解整成一篇文章,附带大量例子,让其更加好理解. 在编程语言中,函数的应用: 1. 代码块重复,这时候必 ...

  8. PHP进阶,使用交互模式进行快速测试实验?

    额,那啥,PHP很强,大家都知道哈.不过呢,在搞PHP里的人中,自然也要分高下的.当然了,我更喜欢用好玩来形容了. 什么叫做快速开发?我觉得,快就得快到随手写几个字,就能让代码跑起来!那么,PHP能做 ...

  9. OLAP与数据仓库------《Designing Data-Intensive Applications》读书笔记4

    由于第三章的内容比较多,这里我们拆分成两篇读书笔记来记录.上一章我们聊了聊如何数据库是如何实现存储和检索的,今天这篇我们继续来看看OLTP与OLAP存储引擎的区别与联系. 1.OLTP与OLAP 联机 ...

  10. VMware仅主机模式虚拟机无法ping通物理机

    问题描述 在VMware Workstation中新建了一个虚拟机CentOS7,网络适配器选择的是"仅主机模式",结果,物理机ping不通虚拟机,虚拟机也ping不通物理机. 原 ...