当前,对xml的使用非常广泛,读取和设置xml配置文件是我们最常用的操作。常见C/C++ XML解析器有Tinyxml、XERCES、squashxml、xmlite、pugxml、libxml等等,这些解析器有些是支持多语言的,有些只是单纯C/C++的。
TinyXML是目前非常流行的一款基于DOM模型的XML解析器,简单易用且小巧玲珑,非常适合存储简单数据,配置文件,对象序列化等数据量不是很大的操作。这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树。
下载:https://sourceforge.net/projects/tinyxml/
安装:解压缩tinyXML后,将这六个文件添加到你的C++工程中,分别是tinystr.h、tinystr.cpp、tinyxml.h、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.cpp。在需要操作xml文件的地方,使用如下代码,就可以引入TinyXML类库
TiXmlBase:整个TinyXML模型的基类。
TiXmlAttribute:对应于XML中的元素的属性。
TiXmlNode:对应于DOM结构中的节点。
TiXmlComment:对应于XML中的注释
TiXmlDeclaration:对应于XML中的申明部分,即<?versiong=“1.0” ?>。
TiXmlDocument:对应于XML的整个文档。
TiXmlElement:对应于XML的元素。
TiXmlText:对应于XML的文字部分
TiXmlUnknown:对应于XML的未知部分。
TiXmlHandler:定义了针对XML的一些操作。
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文件头()
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
#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用法小结