轉載: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;
}