天天看點

C++ tinyxml處理XML檔案

  XML作為資料傳遞的一種方式,在Android中有友善使用的解析方式,在windows平台下面也有很多解析xml檔案的開源庫。我經常使用的是tinyxml。

1.加載XML檔案

int loadXML()
{
	TiXmlDocument doc;
	if(!doc.LoadFile("C:\\Documents and Settings\\tcxt-yangzy\\桌面\\Task.xml"))
	{
		cerr << doc.ErrorDesc() << endl;
		return -1;
	}

	TiXmlElement* root = doc.FirstChildElement();
	if(root == NULL)
	{
		cerr << "Failed to load file: No root element." << endl;
		doc.Clear();
		return -2;
	}

	string str_count = root->Attribute("Count");
	int my_task_count = atoi(str_count.c_str());
	if( my_task_count <= 0 )
	{
		return -1;
	}
	MYTASK* my_task_list = new MYTASK[my_task_count];
	memset( my_task_list , 0 , my_task_count*sizeof(MYTASK) );

	int i = 0;
	for(TiXmlElement* elem_mytask = root->FirstChildElement("MyTask"); elem_mytask != NULL; elem_mytask = elem_mytask->NextSiblingElement("MyTask"))
	{
		//string elemName = elem->Value();
		//string elemText = elem->GetText();
		
		string attr_task_name =UTF8ToANSI( elem_mytask->Attribute("TaskName") ) ;
		string attr_task_author =UTF8ToANSI( elem_mytask->Attribute("TaskAuthor"));
		string attr_task_date =UTF8ToANSI( elem_mytask->Attribute("TaskDate"));
		string attr_task_dd =UTF8ToANSI( elem_mytask->Attribute("DataDictionaryCount"));
		string attr_shape =UTF8ToANSI( elem_mytask->Attribute("ShapeFile"));
		string attr_tiff =UTF8ToANSI( elem_mytask->Attribute("TIFF"));


		TiXmlElement* elem_prj = elem_mytask->FirstChildElement("PrjFile");
		string attr_prj_name =UTF8ToANSI( elem_prj->Attribute("Name") ) ;
		string attr_prj_path =UTF8ToANSI( elem_prj->Attribute("Path"));

		my_task_list[i].task_name = attr_task_name;
		my_task_list[i].task_author = attr_task_author;
		my_task_list[i].task_date = attr_task_date;
		my_task_list[i].data_dictionary_count = attr_task_dd;
		my_task_list[i].shape = attr_shape;
		my_task_list[i].tiff = attr_tiff;
		my_task_list[i].prj.prj_name = attr_prj_name;
		my_task_list[i].prj.prj_path = attr_prj_path;

		int dd_count = atoi(attr_task_dd.c_str());
		if( dd_count > 0)
		{
			my_task_list[i].dd_list = new DATADICTIONARY[dd_count];
			memset( my_task_list[i].dd_list , 0 , dd_count * sizeof( DATADICTIONARY ) );
			int j = 0 ;
			for(TiXmlElement* elem_dd = elem_mytask->FirstChildElement("DataDictionary"); elem_dd != NULL; elem_dd = elem_dd->NextSiblingElement("DataDictionary"))
			{
				string attr_dd_name =UTF8ToANSI( elem_dd->Attribute("Name") ) ;
				string attr_dd_path =UTF8ToANSI( elem_dd->Attribute("Path"));
				my_task_list[i].dd_list[j].dd_name = attr_dd_name;
				my_task_list[i].dd_list[j].dd_path = attr_dd_path;
				j++;
			}
		}
		i++;
	}
	doc.Clear();
	return 0;
}
           
/*!
*  \brief 通過根節點和節點名擷取節點指針。
*
*  \param pRootEle   xml檔案的根節點。
*  \param strNodeName  要查詢的節點名
*  \param Node      需要查詢的節點指針
*  \return 是否找到。true為找到相應節點指針,false表示沒有找到相應節點指針。
*/
bool GetNodePointerByNameEx(TiXmlElement* pRootEle,std::string &strNodeName,string strNodeAttr,string strNodeValue ,TiXmlElement* &Node)
{
	// 假如等于根節點名,就退出
	string attr_value = UTF8ToANSI( pRootEle->Attribute(strNodeAttr.c_str()));
	if (strNodeName==pRootEle->Value() && attr_value == strNodeValue )
	{
		Node = pRootEle;
		return true;
	}

	TiXmlElement* pEle = pRootEle;  
	for (pEle = pRootEle->FirstChildElement(); pEle; pEle = pEle->NextSiblingElement())  
	{  
		//遞歸處理子節點,擷取節點指針
		if(GetNodePointerByNameEx(pEle,strNodeName,strNodeAttr,strNodeValue,Node))
			return true;
	}  

	return 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 指定的節點名。
*  \return 是否成功。true為成功,false表示失敗。
*/
bool DelNode(std::string XmlFile,std::string strNodeName ,string node_arrt, string node_arrt_value)
{
	// 定義一個TiXmlDocument類指針
	TiXmlDocument *pDoc = new TiXmlDocument();
	if (NULL==pDoc)
	{
		return false;
	}

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

	TiXmlElement *pNode = NULL;

	GetNodePointerByNameEx(pRootEle,strNodeName,node_arrt,node_arrt_value,pNode);

	string attr_value = UTF8ToANSI( pNode->Attribute(node_arrt.c_str()));

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

	return false;
}

//修改節點其實和查詢指定節點的值有點類似,也分為兩個函數,一個實作修改文本。另一個負責修改屬性。

bool ModifyNode_Text(const std::string& XmlFile,const std::string& strNodeName,const std::string& strText)
{
	// 定義一個TiXmlDocument類指針
	TiXmlDocument *pDoc = new TiXmlDocument();
	if (NULL==pDoc)
	{
		return false;
	}

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

	TiXmlElement *pNode = NULL;

	GetNodePointerByName(pRootEle,strNodeName.c_str(),pNode);

	if (NULL!=pNode)
	{
		pNode->Clear();  // 首先清除所有文本
		// 然後插入文本,儲存檔案
		TiXmlText *pValue = new TiXmlText(strText.c_str());
		pNode->LinkEndChild(pValue);
		pDoc->SaveFile(XmlFile.c_str());
		return true;
	}
	else
		return false;
}



bool ModifyNode_Attribute(const std::string& XmlFile,const std::string& strNodeName,
						  const std::map<std::string,std::string> &AttMap)
{
	typedef std::pair <std::string,std::string> String_Pair;

	// 定義一個TiXmlDocument類指針
	TiXmlDocument *pDoc = new TiXmlDocument();
	if (NULL==pDoc)
	{
		return false;
	}

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

	TiXmlElement *pNode = NULL;
	GetNodePointerByName(pRootEle,strNodeName,pNode);

	if (NULL!=pNode)
	{
		TiXmlAttribute* pAttr = NULL; 
		std::string strAttName = ("");
		std::string strAttValue = ("");
		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.c_str());
				}
			}

		}  
		pDoc->SaveFile(XmlFile.c_str());
		return true;
	}
	else
	{
		return false;
	}

}

/*!
*  /brief 增加指定節點的文本。
*
*  /param XmlFile xml檔案全路徑。
*  /param strParNodeName 要增加的節點的父節點。
*  /param strNodeName 指定的節點名。
*  /param strText 要增加的文本
*  /return 是否成功。true為成功,false表示失敗。
*/
bool AddNode_Text(const std::string& XmlFile,const std::string& strParNodeName,const std::string& strNodeName,const std::string& strText)
{
	// 定義一個TiXmlDocument類指針
	TiXmlDocument *pDoc = new TiXmlDocument();
	if (NULL==pDoc)
	{
		return false;
	}

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

	TiXmlElement *pNode = NULL;
	GetNodePointerByName(pRootEle,strParNodeName,pNode);

	if (NULL!=pNode)
	{
		// 生成子節點:pNewNode
		TiXmlElement *pNewNode = new TiXmlElement(strNodeName.c_str());
		if (NULL==pNewNode)
		{
			return false;
		}
		// 設定節點文本,然後插入節點
		TiXmlText *pNewValue = new TiXmlText(strText.c_str());
		pNewNode->LinkEndChild(pNewValue);

		pNode->InsertEndChild(*pNewNode);
		pDoc->SaveFile(XmlFile.c_str());
		return true;
	}
	else
		return false;

}

bool AddNode_Text_EX(const std::string& XmlFile,const std::string& strParNodeName,const std::string& strNodeName,const std::string& strText)
{
	// 定義一個TiXmlDocument類指針
	TiXmlDocument *pDoc = new TiXmlDocument();
	if (NULL==pDoc)
	{
		return false;
	}

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

	TiXmlElement *pNode = NULL;
	GetNodePointerByName(pRootEle,strParNodeName,pNode);

	if (NULL!=pNode)
	{
		// 生成子節點:pNewNode
		TiXmlElement *pNewNode = new TiXmlElement(strNodeName.c_str());
		if (NULL==pNewNode)
		{
			return false;
		}
		// 設定節點文本,然後插入節點
		TiXmlText *pNewValue = new TiXmlText(strText.c_str());
		pNewNode->LinkEndChild(pNewValue);

		pNode->InsertEndChild(*pNewNode);
		pDoc->SaveFile(XmlFile.c_str());
		return true;
	}
	else
		return false;

}

/*!
*  /brief 增加節點。
*
*  /param XmlFile xml檔案全路徑。
*  /param strParNodeName 要增加的節點的父節點。
*  /param strNodeName 指定的節點名。
*  /param AttMap 要增加的節點設定的屬性值,這是一個map,前一個為屬性名,後一個為屬性值
*  /return 是否成功。true為成功,false表示失敗。
*/
bool AddNode_Attribute(const std::string& XmlFile
					   ,const std::string& strParNodeName
					   ,const std::string strNodeName
					   ,const std::map<std::string,std::string> &AttMap)
{
	// 定義一個TiXmlDocument類指針
	TiXmlDocument *pDoc = new TiXmlDocument();
	if (NULL==pDoc)
	{
		return false;
	}

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

	TiXmlElement *pNode = NULL;
	GetNodePointerByName(pRootEle,strParNodeName,pNode);

	if (NULL!=pNode)
	{
		// 生成子節點:pNewNode
		TiXmlElement *pNewNode = new TiXmlElement(strNodeName.c_str());
		if (NULL==pNewNode)
		{
			return false;
		}
		// 設定節點的屬性值,然後插入節點
		std::map<std::string,std::string>::const_iterator iter;
		for (iter=AttMap.begin();iter!=AttMap.end();iter++)
		{
			pNewNode->SetAttribute(iter->first.c_str(),iter->second.c_str());
		}

		pNode->InsertEndChild(*pNewNode);
		pDoc->SaveFile(XmlFile.c_str());
		return true;
	}
	else
		return false;
}

bool AddNode_Attribute_EX(const std::string& XmlFile
					   ,std::string strParNodeName//父節點
					   ,std::string strNodeName//目前節點
					   ,string node_attr//目前節點屬性
					   ,string node_attr_value//目前節點屬性内容
					   ,std::map<std::string,std::string> &AttMap)
{
	// 定義一個TiXmlDocument類指針
	TiXmlDocument *pDoc = new TiXmlDocument();
	if (NULL==pDoc)
	{
		return false;
	}

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

	TiXmlElement *pNode = NULL;
	GetNodePointerByNameEx(pRootEle,strParNodeName,node_attr,node_attr_value,pNode);

	if (NULL!=pNode)
	{
		// 生成子節點:pNewNode
		TiXmlElement *pNewNode = new TiXmlElement(strNodeName.c_str());
		if (NULL==pNewNode)
		{
			return false;
		}
		// 設定節點的屬性值,然後插入節點
		std::map<std::string,std::string>::const_iterator iter;
		for (iter=AttMap.begin();iter!=AttMap.end();iter++)
		{
			pNewNode->SetAttribute(iter->first.c_str(),iter->second.c_str());
		}

		pNode->InsertEndChild(*pNewNode);
		pDoc->SaveFile(XmlFile.c_str());
		return true;
	}
	else
		return false;
}

int _tmain(int argc, _TCHAR* argv[])
{
	
	//loadXML();

	//DelNode( XML_PATH,"MyTask","TaskName","我的任務4" );
/*
	//ModifyNode_Text( XML_PATH ,"Tasks" , "321414" );

	map<string , string> arrt ;
	arrt["Count"] = "100";

	//ModifyNode_Attribute(XML_PATH,"MyTask",arrt);

	arrt["TaskName"] = ANSIToUTF8("taskfour");
	arrt["TaskAuthor"] = ANSIToUTF8("王二小");
	arrt["TaskDate"] = "2015-07-10 17:37";
	arrt["DataDictionaryCount"] = "3";
	arrt["ShapeFile"] = "";
	arrt["TIFF"] = "";
	
	//AddNode_Text(XML_PATH,"MyTask","1321","1314546");
	AddNode_Attribute(XML_PATH,"Tasks","MyTask",arrt);
	map<string , string> arrt_prj ;
	arrt_prj["Name"] = "Xian 1980 3 Degree GK CM 103E.prj";
	arrt_prj["Path"] = "Xian 1980 3 Degree GK CM 104E.prj";
	AddNode_Attribute_EX(XML_PATH,"MyTask","PrjFile","TaskName","taskfour",arrt_prj);

	map<string , string> arrt_dd ;
	arrt_dd["Name"] = "dd1";
	arrt_dd["Path"] = "dd1";
	AddNode_Attribute_EX(XML_PATH,"MyTask","DataDictionary","TaskName","taskfour",arrt_dd);

	arrt_dd["Name"] = "dd2";
	arrt_dd["Path"] = "dd2";
	AddNode_Attribute_EX(XML_PATH,"MyTask","DataDictionary","TaskName","taskfour",arrt_dd);

	//new_xml();
	*/

	vector<string> task_name_list;
	vector<string> task_auther_list;
	vector<string> task_date_list;

	//TiXmlDocument* doc = open_task( XML_PATH );
	//

	/*
	TiXmlElement* new_task_node = NULL;
	map<string , string> arrt ;
	arrt["TaskName"] = ANSIToUTF8("taskfour");
	arrt["TaskAuthor"] = ANSIToUTF8("王二小");
	arrt["TaskDate"] = "2015-07-10 17:37";
	arrt["DataDictionaryCount"] = "3";
	arrt["ShapeFile"] = "";
	arrt["TIFF"] = "";
	//add_new_task( doc , arrt , new_task_node );
	new_task_node = add_sub_attribute( doc->RootElement() , "MyTask" , arrt );

	map<string , string> prj_arrt ;
	prj_arrt["Name"] = "Beijing 1954 3 Degree GK CM 102E.prj";
	prj_arrt["Path"] = "Beijing 1954 3 Degree GK CM 102E.prj";
	add_sub_attribute( new_task_node , "ProjFile" , prj_arrt );
	
	map<string , string> dd_arrt ;
	dd_arrt["Name"] = ANSIToUTF8( "标準點一" );
	dd_arrt["Path"] = ANSIToUTF8( "132479标準點一");
	add_sub_attribute( new_task_node , "DataDictionary" , dd_arrt );
	
	modify_task_count( doc , 1 , true );*/

	/*
	TiXmlElement* rootElement = doc->RootElement();  //Class
	TiXmlElement *ChildElement = rootElement->FirstChildElement();
	while ( ChildElement ) 
	{
		const char* attr_name = ChildElement->Attribute("TaskName");
		printf( "%s\n " , UTF8ToANSI( attr_name ) );

		TiXmlElement* prjEle = ChildElement->FirstChildElement("PrjFile");
		const char* prj_name = prjEle->Attribute("Name");
		printf( "%s\n " , UTF8ToANSI( prj_name ) );

		TiXmlElement* ddEle = ChildElement->FirstChildElement("DataDictionary");
		while ( ddEle )
		{
			const char* dd_name = ddEle->Attribute("Name");
			printf( "%s\n " , UTF8ToANSI( dd_name ) );

			ddEle = ddEle->NextSiblingElement();
		}

		ChildElement = ChildElement->NextSiblingElement();

		printf("\n\n");
	}*/

	//close_task(doc);

	TiXmlDocument* des_doc = open_task( XML_PATH );
	TiXmlDocument* src_doc = open_task( XML_SRC_PATH );

	TiXmlElement* return_node = NULL;
	get_node_by_name_date( des_doc->RootElement() , "taskthree" , "2015-07-07 17:52" , return_node );

	//import_task( des_doc , src_doc );
	//close_task( des_doc );
	//close_task( src_doc );

	return 0;
}

void WrittingXML(TiXmlString & xmlFile)  
{  
	TiXmlDeclaration * xmlDec = new TiXmlDeclaration("1.0", "UTF-8", "yes");  
	TiXmlDocument * xmlDocs = new TiXmlDocument();  
	xmlDocs->LinkEndChild(xmlDec);  
	TiXmlElement * element = new TiXmlElement("Document");  
	xmlDocs->LinkEndChild(element);  
	/*TiXmlComment * comment = new TiXmlComment(" This is a list of new books ");  
	element->LinkEndChild(comment);  */
	TiXmlElement * book = new TiXmlElement("Book");  
	book->SetAttribute("Name", "How to use TinyXML");  
	element->LinkEndChild(book);  
	TiXmlElement * author = new TiXmlElement("Author");  
	TiXmlText * Authortext = new TiXmlText("Leezhm");  
	author->LinkEndChild(Authortext);  
	book->LinkEndChild(author);  
	TiXmlElement * date = new TiXmlElement("Date");  
	TiXmlText * Datetext = new TiXmlText("2009-3-30");  
	date->LinkEndChild(Datetext);  
	book->LinkEndChild(date);  
	xmlDocs->SaveFile(xmlFile.c_str());  
	delete xmlDocs;  
} 
           
代碼下載下傳:
http://download.csdn.net/detail/wb175208/9824351
           

繼續閱讀