天天看点

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

继续阅读