当前位置: 首页 > news >正文

轻量级TinyXml2的应用

TinyXml2库基本介绍

        TinyXML2 是 simple、small、efficient 的基于DOM (Document Object Model,文档对象模型) 的开源 C++ XML文件解析库,可以很方便地应用到现有的项目中 。目前,TinyXML1 开发已经停止,所有的开发都转移到了 TinyXML2。TinyXML2 适用于大部分 C/C++ 的项目,经得住考验,是最好的选择。较 TinyXML1 而言,TinyXML2 化繁为简,使用时只需要包含两个文件,而 TinyXML1 需要包含 6 个文件,一般生成静态链接库供项目使用。

        TinyXML2 使用了与 TinyXML1 相似的 API,并且拥有丰富的测试案例。但 TinyXML2 解析器相对 TinyXML1 在代码上是完全重写,它使用更少的内存,效率更高

        TinyXML2 无需 STL,也放弃了对 STL 支持。所有字符串查询均使用 C 风格字符串const char*来表示,省去 string 类型对象的构造,使代码更加简洁。

下载和使用

GitHub - leethomason/tinyxml2: TinyXML2 is a simple, small, efficient, C++ XML parser that can be easily integrated into other programs.

下载后只需要将将tinyxml2.h和tinyxml2.cpp引入项目即可,极为方便。

项目中使用示例

xmlHandle头文件

#pragma once

#include "TinyXml2/tinyxml2.h"
#include<string>
#include<map>

using namespace::tinyxml2;

namespace XmlHandle 
{
	int CreateXml(const char*xmlpath,const char*rootname);//创建
	int LoadXml(tinyxml2::XMLDocument&doc, const char*xmlpath);//从路径xmlpath加载
	int SaveXml(tinyxml2::XMLDocument&doc, const char*xmlpath);//保存xml文件到xmlpath
	//插入节点 可以携带属性
	XMLElement* InsertNode(tinyxml2::XMLDocument&doc, XMLElement*ParentRoot, const char*element, const char*value, const std::map<std::string, std::string>&AttributeMap = std::map<std::string, std::string>(), bool HasAttribute = false);

	//查询节点
	XMLElement* QueryNodeByName(tinyxml2::XMLDocument&doc, const char*NodeName, const char*Atttibute = nullptr, const char*AttributeValue = nullptr, bool hasAttribute = false);
	std::string QueryValueByName(XMLElement*node);
	std::string QueryAttByName(XMLElement*node,const char*attName);
	//删除节点
	int DeleteNode(tinyxml2::XMLDocument&doc, XMLElement*ParentRoot, const char*element, const char*Atttibute = nullptr, bool isAttribute = false);
	//更新节点值或属性
	XMLElement* UpdateNode(tinyxml2::XMLDocument&doc, XMLElement*Element, const char*element, const char*value, const char*Atttibute = nullptr, const char*AttributeValue = nullptr, bool HasAttribute = false);
	//序列化
	std::string DocToString(tinyxml2::XMLDocument&doc);
	//反序列化
	bool stringToDoc(const std::string&SmlStr, tinyxml2::XMLDocument&doc);

};

xmlHandle的实现文件

#include "XmlHandle.h"


int XmlHandle::CreateXml(const char*xmlpath,const char*rootname)
{
	const char*declartion = "<?xml version = \"1.0\" encoding = \"UTF-8\" ?>";
	XMLDocument doc;
	doc.Parse(declartion);//Parse an XML file from a character string. 覆盖
	XMLElement*root = doc.NewElement(rootname);//新增根节点
	doc.InsertEndChild(root);//InsertFirstChild InsertAfterChild InsertEndChild root下第一个 次于... 最后一个
	XMLError ErrorId = doc.SaveFile(xmlpath);
	return ErrorId;

}


int XmlHandle::LoadXml(XMLDocument&doc, const char*xmlpath)
{
	return doc.LoadFile(xmlpath);
}

int XmlHandle::SaveXml(tinyxml2::XMLDocument&doc, const char*xmlpath)
{
	return doc.SaveFile(xmlpath);
}

XMLElement* XmlHandle::InsertNode(tinyxml2::XMLDocument&doc, XMLElement*ParentRoot, const char*element, const char*value, const std::map<std::string, std::string>&AttributeMap, bool HasAttribute)
{
	XMLElement* Node = doc.NewElement(element);
	if (HasAttribute)
	{
		for (auto iter : AttributeMap)
		{
			Node->SetAttribute(iter.first.c_str(), iter.second.c_str());
		}
	}
	if (value != nullptr)//空则表示有子节点
	{
		Node->InsertEndChild(doc.NewText(value));
	}
	if (ParentRoot)
	{
		ParentRoot->InsertEndChild(Node);
	}
	else
	{
		doc.InsertEndChild(Node);
	}
	return  Node;
}


XMLElement* XmlHandle::QueryNodeByName(XMLDocument&doc, const char*NodeName, const char*Atttibute , const char*AttributeValue, bool hasAttribute)
{
	XMLElement*root = doc.RootElement();
	XMLElement* userNode = root->FirstChildElement(NodeName);
	while (!userNode)
	{
		if ((hasAttribute&&userNode->Attribute(Atttibute) == AttributeValue) || (!hasAttribute))
		{
			break;
		}
		userNode = userNode->NextSiblingElement();//下一个兄弟节点
	}
	return userNode;
}

std::string XmlHandle::QueryValueByName(XMLElement*node)
{
	if (node)
	{
		return node->GetText();
	}
	return std::string();
}

std::string XmlHandle::QueryAttByName(XMLElement*node, const char*attName)
{
	if (node)
	{
		return node->Attribute(attName);
	}
	return std::string();
}

int XmlHandle::DeleteNode(XMLDocument&doc, XMLElement*ParentRoot,const char*element, const char*Atttibute, bool HasAttribute)
{
	if (ParentRoot)
	{
		if (element)
		{
			ParentRoot->DeleteChild(ParentRoot->FirstChildElement(element));
		}
		if (HasAttribute)
		{
			ParentRoot->DeleteAttribute(Atttibute);
		}
		return 0;
	}
	return -1;
}

XMLElement* XmlHandle::UpdateNode(tinyxml2::XMLDocument&doc, XMLElement*Element, const char*element, const char*value, const char*Atttibute, const char*AttributeValue, bool HasAttribute)
{
	if (Element)
	{
		Element->SetText(value);
		if (HasAttribute)
		{
			Element->SetAttribute(Atttibute, AttributeValue);
		}
		return Element;
	}
	return nullptr;
}

std::string XmlHandle::DocToString(tinyxml2::XMLDocument&doc)
{
	XMLPrinter printer;
	doc.Print(&printer);
	return printer.CStr();
}


bool XmlHandle::stringToDoc(const std::string&SmlStr, tinyxml2::XMLDocument&doc)
{
	XMLError XmlErr = doc.Parse(SmlStr.c_str(), SmlStr.size());
	return XmlErr == XML_SUCCESS;
}

 xmlHandle的使用举例

void Qxmltest::TestXML()
{
	//创建
	using namespace XmlHandle;
	std::string path = QDir::currentPath().toStdString() + "/Test.xml";
	int ret = CreateXml(path.c_str(),"XmlDB");


	//增加节点
	tinyxml2:: XMLDocument doc;
	if (0 == LoadXml(doc, path.c_str()))
		//QueryNodeByName
	{
		using AttMap = std::map<std::string, std::string>;
		AttMap Attritubte;
		Attritubte.insert(std::make_pair("Name", "ZahngSan"));
		Attritubte.insert(std::make_pair("Gneder", "Men"));
		XMLElement*UserNode = InsertNode(doc, doc.RootElement(), "User", nullptr, Attritubte, true);
		if (UserNode)
		{
			InsertNode(doc,  UserNode, "hobby", "play games");
			InsertNode(doc,  UserNode, "Pet", "Dog");
			InsertNode(doc,  UserNode, "Language", "Chinese");
			InsertNode(doc,  UserNode, "height", "180");
			InsertNode(doc,  UserNode, "weight", "80");
		}

		Attritubte.clear();
		Attritubte.insert(std::make_pair("Name", "LiSi"));
		Attritubte.insert(std::make_pair("Gneder", "Men"));
		UserNode = InsertNode(doc,  doc.RootElement(), "User", nullptr, Attritubte, true);
		if (UserNode)
		{
			InsertNode(doc, UserNode, "hobby", "play ping-pang");
			InsertNode(doc, UserNode, "Pet", "Cat");
			InsertNode(doc, UserNode, "Language", "Chinese");
			InsertNode(doc, UserNode, "height", "181");

			AttMap weightAtt;
			weightAtt.insert(std::make_pair("WeightX", "Year"));
			weightAtt.insert(std::make_pair("WeightY", "WeightValue"));
			weightAtt.insert(std::make_pair("WeightZ", "UnKnown"));
 			XMLElement*WNode = InsertNode(doc,  UserNode, "weight", nullptr, weightAtt,true);
		
			AttMap att2020;
			att2020.insert(std::make_pair("Year?", "Yes"));
			att2020.insert(std::make_pair("Weight?", "No"));
			XMLElement*Node2020 = InsertNode(doc, WNode, "2020", "70", att2020, true);
			InsertNode(doc,  WNode, "2021", "73");
			InsertNode(doc,  WNode, "2022", "75");

			//修改
			UpdateNode(doc, Node2020, "2020", "69", "Weight", "Yes", true);

			//删除
			DeleteNode(doc, WNode, "2022", "WeightZ", true);
		}
		//查找
		QString Display;
		XMLElement*ZSNode =  QueryNodeByName(doc,"User","name","ZahngSan",true);
		if (ZSNode)
		{
			Display+=QString(QueryAttByName(ZSNode, "Gneder").c_str())+'\n';
		}

		QString xmlStr =QString::fromStdString(DocToString(doc));
		Display +=xmlStr;

		/*tinyxml2::XMLDocument doc2;
		if (stringToDoc(xmlStr.toStdString(), doc2))
		{
			XMLElement*ZSNode = QueryNodeByName(doc, "User", "name", "LiSi", true);
			if (ZSNode)
			{
				Display += QString(QueryAttByName(ZSNode, "Gneder").c_str()) + '\n';
			}
		}*/

		ui.textEdit_XML->setText(Display);
		SaveXml(doc,path.c_str());
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.dtcms.com/a/14941.html

相关文章:

  • 【Pandas】pandas Series drop
  • FFmpeg Video options
  • qt中实现QListWidget列表
  • Django开发入门 – 4.创建Django app
  • window 11 鼠标右键切换回经典模式
  • 稀土抑烟剂——为汽车火灾安全增添防线
  • 教程 | Proxmox VE(PVE)安装全流程指南(末尾附镜像及快速配置脚本)
  • vue2打包带路径的项目,刷新404问题解决
  • unity 安装Entities
  • 适用于 WinForms 的浏览器控件
  • 【深度学习】Java DL4J 2024年度技术总结
  • ElementUI el-popover弹框背景色设置
  • Kimi实战1/100 - 读接口文档,编写接口
  • 对贵司需求的PLC触摸的远程调试的解决方案
  • 算法06-回溯算法
  • 京东 旋转验证码 分析
  • 伯克利 CS61A 课堂笔记 09 —— Data Abstraction
  • 图书管理项目(spring boot + Vue)
  • Cisco Catalyst交换机和ASR路由器上加vty下的列表时最后的vrf-also命令作用
  • DedeBIZ系统审计小结
  • RabbitMQ的死信队列的产生与处理
  • PHP 超级全局变量
  • 手机用流量怎样设置代理ip?
  • ArcGIS基础知识之ArcMap基础设置——ArcMap选项:常规选项卡设置及作用
  • 蓝桥杯篇---温度传感器 DS18B20
  • visual studio导入cmake项目后打开无法删除和回车
  • 51-ArrayList
  • 【LeetCode Hot100 双指针】移动零、盛最多水的容器、三数之和、接雨水
  • 人工智能之深度学习的革命性突破
  • 【Stable Diffusion部署至GNU/Linux】安装流程