您的位置:首页 > 编程语言 > C语言/C++

c++操作xml

2015-12-12 11:50 471 查看
作者:朱金灿

来源:http://blog.csdn.net/clever101

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

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

[cpp] view
plaincopy

/*! 

*  /brief 获取xml文件的声明。 



*  /param XmlFile xml文件全路径。 

*  /param strVersion  Version属性值 

*  /param strStandalone Standalone属性值 

*  /param strEncoding Encoding属性值 

*  /return 是否成功。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;  

}  

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

     

[cpp] view
plaincopy

/*! 

*  /brief 通过根节点和节点名获取节点指针。 



*  /param pRootEle   xml文件的根节点。 

*  /param strNodeName  要查询的节点名 

*  /param Node      需要查询的节点指针 

*  /return 是否找到。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;  

}   

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

[cpp] view
plaincopy

  /*! 

*  /brief 通过节点查询。 



*  /param XmlFile   xml文件全路径。 

*  /param strNodeName  要查询的节点名 

*  /param strText      要查询的节点文本 

*  /return 是否成功。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)  

   {  

        strText = pNode->GetText();   

        return true;  

   }  

   else  

   {  

        return false;  

   }  

      

}  

/*! 

*  /brief 通过节点查询。 



*  /param XmlFile   xml文件全路径。 

*  /param strNodeName  要查询的节点名 

*  /param AttMap      要查询的属性值,这是一个map,前一个为属性名,后一个为属性值 

*  /return 是否成功。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;  

}  

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

[cpp] view
plaincopy

/*! 

*  /brief 删除指定节点的值。 



*  /param XmlFile xml文件全路径。 

*  /param strNodeName 指定的节点名。 

*  /return 是否成功。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;  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  windows c++