zoukankan      html  css  js  c++  java
  • TinyXml快速入门(二)

    在《TinyXml快速入门(一)》中我介绍了使用TinyXml库如何创建和打印xml文件,下面我介绍使用tinyxml库对xml文件进行一系列的操作,包括获取xml文件声明,查询指定节点、删除指定节点、修改指定节点和增加节点的用法。在《TinyXml快速入门(一)》中我们知道xml文件中的一个节点元素实际包含两种值:属性和文本。其中属性在我看来可以看作是STL中的map,一个属性带一个属性值,map中也是一个键带一个键值。因此查询指定节点、删除指定节点和增加节点必然是需要实现两种方法,删除指定节点只需要实现一种方法。鉴于内容较多,在本文中介绍获取xml文件声明,查询指定节点、删除指定节点的做法,修改指定节点和增加节点的做法在后续的文章介绍。

         首先是获取xml文件声明。xml文件声明包括三方面的内容:Version、Standalone和Encoding。其源码如下:

    /*!
    *  rief 获取xml文件的声明。
    *
    *  param XmlFile xml文件全路径。
    *  param strVersion  Version属性值
    *  param strStandalone Standalone属性值
    *  param strEncoding Encoding属性值
    *   eturn 是否成功。true为成功,false表示失败。
    */
    bool GetXmlDeclare(std::string XmlFile,
                       std::string &strVersion,
                       std::string &strStandalone,
                       std::string &strEncoding)
    {
        // 定义一个TiXmlDocument类指针
        TiXmlDocument *pDoc = new TiXmlDocument();
        if (NULL==pDoc)
        {
            return false;
        }

        pDoc->LoadFile(XmlFile);

          TiXmlNode* pXmlFirst = pDoc->FirstChild();   
          if (NULL != pXmlFirst)  
         {  
              TiXmlDeclaration* pXmlDec = pXmlFirst->ToDeclaration();  
              if (NULL != pXmlDec)  
              {  
                  strVersion = pXmlDec->Version();
                  strStandalone = pXmlDec->Standalone();
                  strEncoding = pXmlDec->Encoding();
              }
          }
          return true;
    }

    我们发现无论查询节点、删除节点、修改节点和增加节点,其实都离不开一个函数,就是根据节点名获取相关节点指针。那么我们就先实现一个根据节点名获取节点指针的函数:

    /*!
    *  rief 通过根节点和节点名获取节点指针。
    *
    *  param pRootEle   xml文件的根节点。
    *  param strNodeName  要查询的节点名
    *  param Node      需要查询的节点指针
    *   eturn 是否找到。true为找到相应节点指针,false表示没有找到相应节点指针。
    */
    bool GetNodePointerByName(TiXmlElement* pRootEle,std::string &strNodeName,TiXmlElement* &Node)
    {
         // 假如等于根节点名,就退出
         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;
    }

    有了这个函数,我们就很容易实现查询节点的相应文本或属性值。

        /*!
    *  rief 通过节点查询。
    *
    *  param XmlFile   xml文件全路径。
    *  param strNodeName  要查询的节点名
    *  param strText      要查询的节点文本
    *   eturn 是否成功。true为成功,false表示失败。
    */
    bool QueryNode_Text(std::string XmlFile,std::string strNodeName,std::string &strText)
    {
        // 定义一个TiXmlDocument类指针
        TiXmlDocument *pDoc = new TiXmlDocument();
        if (NULL==pDoc)
        {
            return false;
        }

        pDoc->LoadFile(XmlFile);
        TiXmlElement *pRootEle = 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;
       }
        
    }


    /*!
    *  rief 通过节点查询。
    *
    *  param XmlFile   xml文件全路径。
    *  param strNodeName  要查询的节点名
    *  param AttMap      要查询的属性值,这是一个map,前一个为属性名,后一个为属性值
    *   eturn 是否成功。true为成功,false表示失败。
    */
    bool QueryNode_Attribute(std::string XmlFile,std::string strNodeName,std::map<std::string,std::string> &AttMap)
    {
        // 定义一个TiXmlDocument类指针
        typedef std::pair <std::string,std::string> String_Pair;

        TiXmlDocument *pDoc = new TiXmlDocument();
        if (NULL==pDoc)
        {
            return false;
        }

        pDoc->LoadFile(XmlFile);
        TiXmlElement *pRootEle = 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;
        }
        return true;
    }

          下面是删除指定节点的函数,其中考虑了删除根节点的情况。

    /*!
    *  rief 删除指定节点的值。
    *
    *  param XmlFile xml文件全路径。
    *  param strNodeName 指定的节点名。
    *   eturn 是否成功。true为成功,false表示失败。
    */
    bool DelNode(std::string XmlFile,std::string strNodeName)
    {
        // 定义一个TiXmlDocument类指针
        TiXmlDocument *pDoc = new TiXmlDocument();
        if (NULL==pDoc)
        {
            return false;
        }

        pDoc->LoadFile(XmlFile);
        TiXmlElement *pRootEle = pDoc->RootElement();
        if (NULL==pRootEle)
        {
            return false;
        }

        TiXmlElement *pNode = NULL;

        GetNodePointerByName(pRootEle,strNodeName,pNode);

        // 假如是根节点
        if (pRootEle==pNode)
        {
              if(pDoc->RemoveChild(pRootEle))
              {
                   pDoc->SaveFile(XmlFile);
                   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))
                     pDoc->SaveFile(XmlFile);
                else
                    return false;
            }
        }
        else
        {
              return false;
        }

         return false;
    }
     
     
  • 相关阅读:
    jquery跨域请求jsonp
    php返回json,xml,JSONP等格式的数据
    chrome常用配置
    html body标签的几个属性 禁用鼠标右键,禁用鼠标选中文字等
    jquery form表单序列号
    php实时输出内容能够
    php Xdebug调试
    jsonp的简单例子
    web调试的一些小技巧
    jq动态增加的button标签click回调失效的问题,即动态增加的button标签绑定事件$("button.class").click(function)无效
  • 原文地址:https://www.cnblogs.com/lvdongjie/p/4504848.html
Copyright © 2011-2022 走看看