天天看點

C++庫(TinyXml)的安裝和使用

1,什麼是TinyXml

目前,對xml的使用非常廣泛,讀取和設定xml配置檔案是我們最常用的操作。常見C/C++ XML解析器有Tinyxml、XERCES、squashxml、xmlite、pugxml、libxml等等,這些解析器有些是支援多語言的,有些隻是單純C/C++的。

TinyXML是目前非常流行的一款基于DOM模型的XML解析器,簡單易用且小巧玲珑,非常适合存儲簡單資料,配置檔案,對象序列化等資料量不是很大的操作。這個解析庫的模型通過解析XML檔案,然後在記憶體中生成DOM模型,進而讓我們很友善的周遊這棵XML樹。

2,下載下傳和安裝TinyXml

下載下傳:https://sourceforge.net/projects/tinyxml/

安裝:解壓縮tinyXML後,将這六個檔案添加到你的C++工程中,分别是tinystr.h、tinystr.cpp、tinyxml.h、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.cpp。在需要操作xml檔案的地方,使用如下代碼,就可以引入TinyXML類庫
           
3,TinyXml類結構

TiXmlBase:整個TinyXML模型的基類。

TiXmlAttribute:對應于XML中的元素的屬性。

TiXmlNode:對應于DOM結構中的節點。

TiXmlComment:對應于XML中的注釋

TiXmlDeclaration:對應于XML中的申明部分,即<?versiong=“1.0” ?>。

TiXmlDocument:對應于XML的整個文檔。

TiXmlElement:對應于XML的元素。

TiXmlText:對應于XML的文字部分

TiXmlUnknown:對應于XML的未知部分。

TiXmlHandler:定義了針對XML的一些操作。

4,常用方法
TiXmlDocument doc;doc.LoadFile("test.xml");
TiXmlElement *root = doc.FirstChildElement();//擷取根節點元素
QString ElementName = root->Value(); //擷取元素名
bool Children = root->NoChildren(); //判斷該元素是否有子元素 傳回true 有,false 沒有
TiXmlElement *child = root->FirstChildElement(); //擷取root元素下的第一個子元素
child = root->FirstChildElement("major"); //擷取root元素的子元素指定元素名字
TiXmlElement *brother = child->NextSiblingElement(); //擷取child元素的下一個兄弟元素
brother = child->NextSiblingElement("specVersion"); //擷取child元素的兄弟元素指定元素名字
QString text = brother->GetText(); //擷取brother元素的值
TiXmlAttribute *Attribute = brother->FirstAttribute(); //擷取brother元素的第一個屬性
QString AttributeName = Attribute->Name(); //擷取Attribute屬性的名字QString 
AttributeValue = Attribute->Value(); //擷取Attribute屬性的值
AttributeValue = brother->Attribute("AttributeName"); //擷取brother的屬性名為(AttributeName)的值
TiXmlDocument *myDocument = new TiXmlDocument(); //建立一個XML檔案
TiXmlDeclaration *pDeclaration=new TiXmlDeclaration("1.0","UTF-8",""); //建立xml檔案頭(<?xml version="1.0" encoding="UTF-8" ?>)
myDocument->LinkEndChild(pDeclaration); //加入将xml檔案頭加入文檔中
TiXmlElement *BUSINESS=new TiXmlElement("BUSINESS"); //建立一個元素節點
myDocument->LinkEndChild(BUSINESS); //加入BUSINESS元素節點到文檔中
TiXmlElement *COUNTRY = new TiXmlElement("COUNTRY"); //建立兩個節點
TiXmlElement *PLANET = new TiXmlElement("PLANET");
BUSINESS->LinkEndChild(PLANET); //将建立的節點加到BUSINESS下一級
BUSINESS->LinkEndChild(COUNTRY);
TiXmlText *PLANETtxt = new TiXmlText("one"); //添加節點内的文本
TiXmlText *COUNTRYtxt = new TiXmlText("china");
COUNTRY->LinkEndChild(COUNTRYtxt);
PLANET->LinkEndChild(PLANETtxt);
myDocument->SaveFile("test.xml"); //儲存xml
           
5,讀寫xml
#include "stdafx.h"
#include "Configer.h"
#include <Windows.h>
#include <iostream>

//UTF-8 轉換成 GB2312
char* U2G(const char* utf8)
{

	int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);

	wchar_t* wstr = new wchar_t[len + 1];
	memset(wstr, 0, len + 1);

	MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len);
	len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);

	char* str = new char[len + 1];
	memset(str, 0, len + 1);

	WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);

	if (wstr)
	{
		delete[] wstr;
		wstr = NULL;
	}
	return str;
}
//GB2312 轉換成 UTF8
char* G2U(const char* gb2312)
{
	int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0);
	wchar_t* wstr = new wchar_t[len + 1];
	memset(wstr, 0, len + 1);
	MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len);
	len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
	char* str = new char[len + 1];
	memset(str, 0, len + 1);
	WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
	if (wstr) delete[] wstr;
	return str;
}

Configer::Configer()
{
}

Configer::~Configer()
{
}
std::string Configer::FilePath()
{
	std::string strPath;
	HMODULE hModule = GetModuleHandle(NULL);	//得到某一子產品的句柄
	char cFilePath[MAX_PATH] = { 0 };
	GetModuleFileNameA(hModule, cFilePath, MAX_PATH);		//獲得目前運作程式的絕對路徑

	std::string strModulFullPath = cFilePath;
	size_t npos = strModulFullPath.rfind("\\", strModulFullPath.length());		//查找字元串在目前字元串中最後一次出現的位置
	if (npos != std::string::npos)		//如果沒找到,傳回一個特别的标志c++中用npos表示,我這裡npos取值是4294967295,
	{
		strPath = strModulFullPath.substr(0, npos);
	}

	return strPath + "\\cfg.xml";
}
bool Configer::Save()
{
	std::shared_ptr<TiXmlDocument> doc(new TiXmlDocument);		//建立XML文檔對象
	TiXmlDeclaration *dec = new TiXmlDeclaration("1.0", "UTF-8", "");	//文檔描述
	TiXmlElement *net = new TiXmlElement("net");		//建立一個根節點
	doc->LinkEndChild(net);		//連結到文檔對象下

	TiXmlElement *tradeNet = new TiXmlElement("TradeNet");
	net->LinkEndChild(tradeNet);		//連結到 net 節點下
	tradeNet->SetAttribute("ip", "127.0.0.1");		//設定節點屬性
	tradeNet->SetAttribute("port", "18068");

	TiXmlElement *quoteNet = new TiXmlElement("QuoteNet");
	net->LinkEndChild(quoteNet);
	quoteNet->SetAttribute("ip", "127.0.0.2");
	quoteNet->SetAttribute("port", "18069");

	TiXmlElement *account = new TiXmlElement("Account");
	doc->LinkEndChild(account);

	TiXmlElement *acc = new TiXmlElement("account");
	account->LinkEndChild(acc);
	acc->SetAttribute("acc", "123456");

	TiXmlElement *acc1 = new TiXmlElement("account");
	account->LinkEndChild(acc1);
	acc1->SetAttribute("acc", "589456");

	return doc->SaveFile(FilePath().c_str());		//儲存文檔
}
bool Configer::Load()
{
	std::shared_ptr<TiXmlDocument> doc(new TiXmlDocument);
	if (!doc->LoadFile(FilePath().c_str()))		//加載檔案
	{
		std::cout << doc->ErrorDesc() << std::endl;
		return false;
	}

	TiXmlElement *net = doc->FirstChildElement("Account");		//索引到節點
	if (net == nullptr)
	{
		return false;
	}
	TiXmlElement *node = net->FirstChildElement("account");		//索引到節點
	while (node)	//周遊節點
	{
		std::string acc = node->Attribute("acc");
		node = node->NextSiblingElement();		//将目前節點指針指向下一個節點
		
	}
	return true;
}
           
詳細用法可參照大神部落格TinyXML用法小結

繼續閱讀