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用法小結