XML --- tinyxml1

轉載:http://www.cnblogs.com/clever101/archive/2010/04/06/1705798.html#2716246


作者:朱金燦

來源:http://www.cnblogs.com/clever101

 

在《TinyXml快速入門(一)》中我介紹了使用TinyXml庫如何創建和打印xml文件,下面我介紹使用tinyxml庫對xml文件進行一系列的操作,包括獲取xml文件聲明,查詢指定節點、刪除指定節點、修改指定節點和增加節點的用法。在TinyXml快速入門(一)》中我們知道xml文件中的一個節點元素實際包含兩種值:屬性和文本。其中屬性在我看來可以看作是STL中的map,一個屬性帶一個屬性值,map中也是一個鍵帶一個鍵值。因此查詢指定節點、刪除指定節點和增加節點必然是需要實現兩種方法,刪除指定節點只需要實現一種方法。鑑於內容較多,在本文中介紹獲取xml文件聲明,查詢指定節點、刪除指定節點的做法,修改指定節點和增加節點的做法在後續的文章介紹。

 

     首先是獲取xml文件聲明。xml文件聲明包括三方面的內容:Version、Standalone和Encoding。其源碼如下:

複製代碼
/*!
*  \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;
}
複製代碼

我們發現無論查詢節點、刪除節點、修改節點和增加節點,其實都離不開一個函數,就是根據節點名獲取相關節點指針。那麼我們就先實現一個根據節點名獲取節點指針的函數:

複製代碼
/*!
*  \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;
}
複製代碼

有了這個函數,我們就很容易實現查詢節點的相應文本或屬性值。

複製代碼
    /*!
*  \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)
   {
        
const char* psz = pNode->GetText(); 
       
if (NULL==psz)
       {
        strText 
= _T("");
        }
       
else
       {
         strText 
= psz;
        }
        
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;
}
複製代碼

      下面是刪除指定節點的函數,其中考慮了刪除根節點的情況。

複製代碼
/*!
*  \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;
}


複製代碼


 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章