轻量级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());}
}
相关文章:
轻量级TinyXml2的应用
TinyXml2库基本介绍 TinyXML2 是 simple、small、efficient 的基于DOM (Document Object Model,文档对象模型) 的开源 C XML文件解析库,可以很方便地应用到现有的项目中 。目前,TinyXML1 开发已经停止,所有…...
DeepSeek正重构具身大模型和人形机器人赛道!
中国人工智能公司DeepSeek(深度求索)以“低成本、高效率、强开放”的研发范式横空出世,火遍并震撼全球科技圈;DeepSeek展现出来的核心竞争力,除了低成本及推理能力,更重要的是开源模型能力追赶上了最新的闭…...
centos7 升级openssl并安装python3
参考文章:https://www.cnblogs.com/chuanzhang053/p/17653635.html 卸载已有版本 yum remove -y openssl openssl-devel下载1.1版本 wget https://www.openssl.org/source/openssl-1.1.1v.tar.gztar -zxf openssl-1.1.1v.tar.gz 查看openssl.conf文件的目录 fin…...
Linux库制作与原理:【静态库】【动态库】【目标文件】【ELF文件】【ELF从形成到假造轮廓】【理解链接和加载】
目录 一.什么是库 二.静态库 2.1创建静态库 我们在之前的路径下新建lib使用我们自己的库 2.2 使用makefile生成静态库 三.动态库 3.1动态库生成 3.2动态库使用 3.3库运行搜索路径 四.目标文件 五.ELF文件 六.ELF从形成到加载轮廓 6.1ELF形成可执行 6.2 ELF可执行文…...
2025前端面试题
2025前端面试题 uniappuniapp如何打包发版到线上 vuekeep-alive 有哪几个生命周期vue3构建项目vue如何封装组件vue2的响应式原理vue3的响应式原理vue3和2的区别Vuex中的重要核心属性有哪些?Vue-router有哪几种路由守卫 es6数组去重的方法slice与splice的区别数组有哪…...
Win7本地化部署deepseek-r1等大模型详解
参考链接 在Windows 7操作系统,基于llama.cpp本地化部署 deepseek-r1模型的方法 2025-02-08 2G内存Windows7运行deepseek-r1:1.5b 这两个链接写的可能不够详细,有同学私信问实现过程,这里进一步解释一下。 一、准备 需要准备的大模型、工具…...
【ubuntu24.04】 强制重启导致大模型的磁盘挂载出错
挂载NTFS文件系统出错 各种模型放在了这个机械硬盘上,虽然速度慢,但是好在容量大。大模型在工作,但是程序看起来有问题,导致系统卡死了,然后我重启了,然后报错:wrong fs type bad option &…...
Spring Boot(8)深入理解 @Autowired 注解:使用场景与实战示例
搞个引言 在 Spring 框架的开发中,依赖注入(Dependency Injection,简称 DI)是它的一个核心特性,它能够让代码更加模块化、可测试,并且易于维护。而 Autowired 注解作为 Spring 实现依赖注入的关键工具&…...
【linux】在 Linux 服务器上部署 DeepSeek-r1:70b 并通过 Windows 远程可视化使用
【linux】在 Linux 服务器上部署 DeepSeek-r1:70b 并通过 Windows 远程可视化使用 【承接商业广告,如需商业合作请+v17740568442】 文章目录 【linux】在 Linux 服务器上部署 DeepSeek-r1:70b 并通过 Windows 远程可视化使用个人配置详情一、安装ollama二、下载deepseek版本…...
【AI大模型】Ollama部署本地大模型DeepSeek-R1,交互界面Open-WebUI,RagFlow构建私有知识库
文章目录 DeepSeek介绍公司背景核心技术产品与服务应用场景优势与特点访问与体验各个DeepSeek-R系列模型的硬件需求和适用场景 Ollama主要特点优势应用场景安装和使用配置环境变量总结 安装open-webui下载和安装docker desktop配置镜像源安装open-webui运行和使用 RagFlow介绍主…...
Unity 命令行设置运行在指定的显卡上
设置运行在指定的显卡上 -force-device-index...
Visual Studio 使用 “Ctrl + /”键设置注释和取消注释
问题:在默认的Visual Studio中,选择单行代码后,按下Ctrl /键会将代码注释掉,但再次按下Ctrl /键时,会进行双重注释,这不是我们想要的。 实现效果:当按下Ctrl /键会将代码注释掉,…...
共用poetry和conda的方法
起因 基于开源项目继续开发,发现该项目使用poetry管理依赖,但本地开发及调试环境依赖conda且未安装原生python,不支持直接安装poetry,因此需要使用conda安装及使用poetry。操作系统:Ubuntu 什么是poetry 一项依赖于…...
教程:使用 Vue 3 和 arco 实现表格合并
1. 功能概述 本教程将介绍如何使用 Vue 3 和 arco 组件库实现表格合并功能。具体来说,我们会根据表格数据中的某个字段(如 type)对表格的某一列(如入库类型列)进行合并,同时将质检说明列合并为一列。 2. …...
Docker 常用命令基础详解(二)
四、容器操作命令 4.1 运行容器 使用docker run命令可以创建并运行一个容器,它就像是一个神奇的 “启动器”,让镜像中的应用程序在容器中运行起来。其基本语法为: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] 其中,OPTIONS…...
uniapp - iconfont下载本地并且运用至项目上
1、项目中创建一个文件夹放置iconfont相关文件,例如src/assets/iconfont(名称自己定义) 2、在iconfont下载项目至本地 3、解压后把文件复制进1的文件夹中 4、修改src/assets/iconfont - iconfont.css里的font-face的src地址,修…...
【前端】自己从头实现一个gpt聊天页面
预览 最小化功能点 主界面:侧边栏会话历史、聊天窗口发送和断开。侧边栏:展示会话列表,每个会话包含多条聊天记录, 通过localstorage本地储存和恢复,会话需要重命名和删除。聊天框:区分一下发送者和回答者…...
数据结构——二叉树(2025.2.12)
目录 一、树 1.定义 (1)树的构成 (2)度 2.二叉树 (1)定义 (2)二叉树的遍历 (3)遍历特性 二、练习 1.二叉树 (1)创建二叉树…...
Vulhub靶机 ActiveMQ任意 文件写入(CVE-2016-3088)(渗透测试详解)
一、开启vulhub环境 docker-compose up -d 启动 docker ps 查看开放的端口 漏洞版本:ActiveMQ在5.14.0之前的版本(不包括5.14.0) 二、访问靶机IP 8161端口 默认账户密码都是admin 1、利用bp抓包,修改为PUT方法并在fileserver…...
跟着李沐老师学习深度学习(十一)
经典的卷积神经网络 在本次笔记中主要介绍一些经典的卷积神经网络模型,主要包含以下: LeNet:最早发布的卷积神经网络之一,目的是识别图像中的手写数字;AlexNet: 是第一个在大规模视觉竞赛中击败传统计算机…...
【微软- Entra ID】Microsoft Entra ID
Microsoft Entra ID是微软提供的基于云的身份和访问管理服务。Microsoft Entra ID是一个全面的解决方案,用于管理身份、执行访问策略以及在云和本地保护您的应用程序和数据。 目录 一、查看 Microsoft Entra ID 微软Entra租户 微软Entra模式 二、比较Microsoft Entra ID与…...
Halcon相机标定
1,前言。 相机的成像过程实质上是坐标系的转换。首先空间中的点由“世界坐标系”转换到“相机坐标系”,然后再将其投影到成像平面(图像物理坐标系),最后再将成像的平面上的数据转换为图像像素坐标系。但是由于透镜的制…...
Linux 配置 MySQL 定时自动备份到另一台服务器
Linux 配置 MySQL 定时自动备份到另一台服务器 前言1、配置服务器通信1.1:配置过程 2、编写自动备份sh脚本文件3:设置定时自动执行 前言 此方案可使一台服务器上的 MySQL 中的所有数据库每天 0 点自动转储为 .sql 文件,然后将文件同步到另一…...
《安富莱嵌入式周报》第350期:Google开源Pebble智能手表,开源模块化机器人平台,开源万用表,支持10GHz HRTIM的单片机,开源CNC控制器
周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版: https://www.bilibili.com/video/BV1YPKEeyEeM/ 《安富莱嵌入式周报》第350期:Google开…...
LabVIEW与小众设备集成
在LabVIEW开发中,当面临控制如布鲁克OPUS红外光谱仪这类小众专业设备的需求,而厂家虽然提供了配套软件,但由于系统中还需要控制其他设备且不能使用厂商的软件时,必须依赖特定方法通过LabVIEW实现设备的控制。开发过程中࿰…...
无人机之无线传输技术!
一、Lightbridge和OcuSync图传技术 Lightbridge技术:这是大疆自主研发的一种专用通信链路技术,使用单向图像数据传输,类似于电视广播塔的数据传输形式。它主要采用2.4GHz频段进行传输,并且可以实现几乎“零延时”的720p高清图像传…...
移远通信边缘计算模组成功运行DeepSeek模型,以领先的工程能力加速端侧AI落地
近日,国产大模型DeepSeek凭借其“开源开放、高效推理、端侧友好”的核心优势,迅速风靡全球。移远通信基于边缘计算模组SG885G,已成功实现DeepSeek模型的稳定运行,并完成了针对性微调。 目前,该模型正在多款智能终端上进…...
rust学习一、入门之搭建简单开发环境
1、搭建开发环境(windows11) a.登录官网 一看就明白,此处略。 b.安装rustup 一看就明白,此处略。 c.安装 cargo script 或者 rust-script script cargo install cargo-script 完成后 注意:时间有一点点久。 测试 cargo s…...
FANUC机器人示教器中如何显示或关闭寄存器或IO的注释信息?
FANUC机器人示教器中如何显示或关闭寄存器或IO的注释信息? 如下图所示,我们打开一个子程序,可以看到程序中的寄存器和IO是显示注释信息的, 如果想关闭注释显示的话,怎么设置? 如下图所示,按下下一页的箭头(NEXT键), 如下图所示,点击“编辑”,在弹出的窗口中,选择“…...
在SpringBoot项目中有k8s配置,但报错
如下报错一般是你没有将k8s的config拷贝到项目里,你可以将k8s主节点的config拷贝一下到项目中。 2025-02-13 09:27:21.873 ERROR 1671 --- [.models.V1Pod-1] i.k.c.informer.cache.ReflectorRunnable : class io.kubernetes.client.openapi.models.V1Pod#Reflec…...
