作者:朱金灿

来源: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. BZOJ1798 AHOI2009 维护数列

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...

  2. CentOS7.4 chrony时间同步服务器部署(替代NTPD)

    Chrony是一个开源的自由软件,它能保持系统时钟与时钟服务器(NTP)同步,让时间保持精确. 它由两个程序组成:chronyd和chronyc. chronyd是一个后台运行的守护进程,用于调整内核 ...

  3. php-自动过滤、自动填充、自动验证

    最近又学到了一些新技巧,和大家分享下. 第一.当一个表单有很大内容时,我们在表单处理页面接收这些表单的值的时候就会重复 接收,于是就有了自动过滤的解决之法(核心就是把数据表里需要的字段接收) 首先:我 ...

  4. 5.Nginx作为web缓存服务器

    Nginx作为web缓存服务器 从0.7.48版本开始,Nginx支持类似Squid的缓存功能.Nginx的web缓存服务主要由proxy_cache相关命令集合fastcgi_cache相关命令集构 ...

  5. c语言中的转义序列

    c中的输出函数printf()可以带以下的转义序列,不同的转义序列会得到不同的结果. 1.\a:警报 2.\b:退格(光标回退一格)3.\f:换页4.\n:换行(光标去到下一行的起始处)5.\r:回车 ...

  6. ThreadLocal 线程本地变量 及 源码分析

    ■ ThreadLocal 定义 ThreadLocal通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量 ...

  7. 4.1 State Snapshot Transfer

    摘要: 出处:黑洞中的奇点 的博客 http://www.cnblogs.com/kelvin19840813/ 您的支持是对博主最大的鼓励,感谢您的认真阅读.本文版权归作者所有,欢迎转载,但请保留该 ...

  8. KVO键值观察的具体实现

    1.KVO简介 KVO是Objective-C对观察者设计模式的一种实现,它提供一种机制,指定一个被观察对象(如A类),当对象中的某个属性发生变化的时候,对象就会接收到通知,并作出相应的处理.在MVC ...

  9. python安装第三方库的三种方法

    使用pip 大多数库都可以通过pip安装,安装方法为,在命令行窗口输入 pip install libname libname为库名 某些库通过pip安装不了,可能是因为没有打包上传到pypi中,可以 ...

  10. Mongo查询关键字