tinyxml2的入门教程

tinyxml2的入门教程

  • 前言
  • 一、tinyxml2 创建xml 文件
  • 二、tinyxml2 添加数据
  • 三、tinyxml2 更改数据
  • 四、tinyxml2 删除数据
  • 五、tinyxml2 打印
  • 总结


前言

xml 是一种标记型文档,有两种基本解析方式:DOM(Document Object Model,文档对象模型)和SAX(Simple APIs for XML,简单应用程序接口)。

在这里插入图片描述

DOM 将 xml 文档全部内容解析成一个对象模型树,通过对这个对象模型进行操作来实现对数据的操作。

  • 优点:
    – 解析成树的结构对象,可以实现增删改操作

  • 缺点:
    – 当 xml 文件过大时,比较占用内存

SAX 以事务为驱动,对 xml 文档从上之下,一行一行解析,当解析到事务对象则返回。

  • 优点:
    – 一行一行解析,内存占用小

  • 缺点:
    – 无能进行增删改操作

目前,有很多库封装了对 xml 文档的操作,例如 mini-xml 、libxml2、Xerces和 tinyxml等。tinyxml2 是其中一个比较简单且高效的 C ++ xml 解析器,只有一个.h 的头文件和一个 . pp 的源文件,可以轻松集成进自己的程序中。

tinyxml2采用DOM解析方式,

在 tinyxml2 中,节点是解析的基本单元,包括 文档节点(XMLDocument)、元素节点(XMLElement)、属性节点(XMLAttribute)和文本节点(XMLText)。对于 xml 文档中数据的增删改查都是基于这些节点进行操作的。

一、tinyxml2 创建xml 文件

首先,最好把 tinyxml2 的头文件和源文件放项目下:

在这里插入图片描述
然后就是引入 tinyxml2 的头文件并链接源文件。这里,用的是 cmake 来构建,将 tinyxml2 文件夹的路径包含进来,然后将源文件链接到 可执行文件上就行。

在这里插入图片描述
最后,假设现在创建一个关于 地图的 xml 数据文件

#include <iostream>
#include "tinyxml2/tinyxml2.h"using namespace std;
using namespace tinyxml2;struct point {double x;double y;point(double x, double y) : x(x), y(y) {};
};// 创建一个XML文件
int createXML(const char *xmlPath) {// 定义文档节点XMLDocument xmlDoc;// 如果文件存在,则返回-1if (xmlDoc.LoadFile(xmlPath) != XML_ERROR_FILE_NOT_FOUND) {cout << "The xml file is exits" << endl;return -1;}// 创建根节点 <MAP>XMLElement *root = xmlDoc.NewElement("MAP");xmlDoc.InsertFirstChild(root);// 创建根节点下的 header 元素节点XMLElement *header = xmlDoc.NewElement("header");root->InsertFirstChild(header);// 设置 header 元素节点的属性header->SetAttribute("type", "");header->SetAttribute("name", "两驱MRL1300-无反识别");// 创建并设置 header 节点下的 min_pos 和 max_pos 元素节点XMLElement *min_pos = xmlDoc.NewElement("min_pos");min_pos->SetAttribute("x", "-46.00000");min_pos->SetAttribute("y", "-57.000000");header->InsertFirstChild(min_pos);XMLElement *max_pos = xmlDoc.NewElement("max_pos");max_pos->SetAttribute("x", "91.00000");max_pos->SetAttribute("y", "43.000000");header->InsertFirstChild(max_pos);// 在根节点下 加个注释root->InsertNewComment("This is a comment");// 在根节点下 加入 footer 元素节点,并设置文本内容XMLElement *footer = xmlDoc.NewElement("footer");footer->InsertNewText("This is a footer");root->InsertEndChild(footer);// 保存 xml 文件return xmlDoc.SaveFile(xmlPath);
}int main(int argc, char *argv[]) {srand(unsigned(time(NULL)));const char *filename = "MAP.xml";if(createXML(filename) != XML_SUCCESS){cout<<"Create xml file failed"<<endl;return 0;}
}

没指定决定路径的话,可以在编译文件夹中看到已经创建了一个 MAP.xml 文件

在这里插入图片描述

二、tinyxml2 添加数据

现在,为刚创建的 MAP.xml 文件,添加一些点云坐标

int addXML(const char *XMLPath) {// 文档节点 xmlDocXMLDocument xmlDoc;if (xmlDoc.LoadFile(XMLPath) != XML_SUCCESS) {cout << "The xml file is not exits" << endl;return -1;}// 获取文档节点的 根节点 rootXMLElement *root = xmlDoc.RootElement();// 添加一些随机坐标点for (int i = 0; i < 100; i++) {point p(rand() * 0.001, rand() * 0.002);// 定义坐标元素节点 pointXMLElement *point = xmlDoc.NewElement("point");// 设置元素节点 point 的属性和值point->SetAttribute("x", p.x);point->SetAttribute("y", p.y);// 将元素节点 point 添加到根节点 root下root->InsertEndChild(point);}// 保存 xml 文件return xmlDoc.SaveFile(XMLPath);
}

可以看到,已经在root节点中加入了 坐标元素了

在这里插入图片描述

三、tinyxml2 更改数据

更改操作里面就用到了 查询 操作(判断):将 x 属性值为0 的所有点元素的 y 属性值都改为2,在改之前,先添加一些x为0的点元素,在addXML()中加入:

// 添加一些指定点for (int i = 0; i < 100; i++) {point p(0,  1);// 定义坐标元素节点 pointXMLElement *point = xmlDoc.NewElement("point");// 设置元素节点 point 的属性和值point->SetAttribute("x", p.x);point->SetAttribute("y", p.y);// 将元素节点 point 添加到根节点 root下root->InsertEndChild(point);}

在随机坐标点下就有了指定坐标点了

在这里插入图片描述

然后再进行查询并修改这些点

int modifyXML(const char *XMLPath) {// 文档节点XMLDocument xmlDoc;if (xmlDoc.LoadFile(XMLPath) != XML_SUCCESS) {cout << "The xml file is not exits" << endl;return -1;}// 获取 文档节点中的 root 根节点XMLElement *root = xmlDoc.RootElement();// 定义要修改的元素节点XMLElement *point = root->FirstChildElement("point");// 将所有 x 属性为 0 的 point 的 y 属性值都改为 2while (point != nullptr) {const char *x = point->Attribute("x");if (x && strcmp(x, "0") == 0) {point->SetAttribute("y", 2);cout << "modify done" << endl;}point = point->NextSiblingElement("point");}// 保存return xmlDoc.SaveFile(XMLPath);
}

这样,就将 x 属性值为 0 点的 y 属性值改为2了

在这里插入图片描述

四、tinyxml2 删除数据

这里,删除 x 属性值为 0 的 point 元素。

int deleteXML(const char *XMLPath) {// 文档节点XMLDocument xmlDoc;if (xmlDoc.LoadFile(XMLPath) != XML_SUCCESS) {cout << "The xml file is not exits" << endl;return -1;}// 获取 根节点 rootXMLElement *root = xmlDoc.RootElement();// 准备要被删除的元素XMLElement *point = root->FirstChildElement("point");while (point != nullptr) {const char *x = point->Attribute("x");// 删除 x 属性值 为 0 的 point 元素if (x && strcmp(x, "0") != 0) {point = point->NextSiblingElement("point");} else {XMLElement *delete_point = point;point = point->NextSiblingElement("point");root->DeleteChild(delete_point);cout << "delete done" << endl;}}// 保存return xmlDoc.SaveFile(XMLPath);
}

这样, x 属性值为 0 的 point 元素就被全部删除了

在这里插入图片描述

五、tinyxml2 打印

void printXML(const char *XMLPath) {// 文档节点XMLDocument xmlDoc;if (xmlDoc.LoadFile(XMLPath) != XML_SUCCESS) {cout << "The xml file is not exits" << endl;return;}XMLPrinter printer;xmlDoc.Print(&printer);cout << printer.CStr() << endl;
}

在这里插入图片描述

总结

tinyxml2 解析 xml 文件的过程操作还是比较简单易上手的。最后,完整代码如下:

#include <iostream>
#include "tinyxml2/tinyxml2.h"using namespace std;
using namespace tinyxml2;struct point {double x;double y;point(double x, double y) : x(x), y(y) {};
};// 创建一个XML文件
int createXML(const char *xmlPath) {// 定义文档节点XMLDocument xmlDoc;// 如果文件存在,则返回-1if (xmlDoc.LoadFile(xmlPath) != XML_ERROR_FILE_NOT_FOUND) {cout << "The xml file is exits" << endl;return -1;}// 创建根节点 <MAP>XMLElement *root = xmlDoc.NewElement("MAP");xmlDoc.InsertFirstChild(root);// 创建根节点下的 header 元素节点XMLElement *header = xmlDoc.NewElement("header");root->InsertFirstChild(header);// 设置 header 元素节点的属性header->SetAttribute("type", "");header->SetAttribute("name", "激光点云地图");// 创建并设置 header 节点下的 min_pos 和 max_pos 元素节点XMLElement *min_pos = xmlDoc.NewElement("min_pos");min_pos->SetAttribute("x", "-46.00000");min_pos->SetAttribute("y", "-57.000000");header->InsertFirstChild(min_pos);XMLElement *max_pos = xmlDoc.NewElement("max_pos");max_pos->SetAttribute("x", "91.00000");max_pos->SetAttribute("y", "43.000000");header->InsertFirstChild(max_pos);// 在根节点下 加个注释root->InsertNewComment("This is a comment");// 在根节点下 加入 footer 元素节点,并设置文本内容XMLElement *footer = xmlDoc.NewElement("footer");footer->InsertNewText("This is a footer");root->InsertEndChild(footer);// 保存 xml 文件return xmlDoc.SaveFile(xmlPath);
}int addXML(const char *XMLPath) {// 文档节点 xmlDocXMLDocument xmlDoc;if (xmlDoc.LoadFile(XMLPath) != XML_SUCCESS) {cout << "The xml file is not exits" << endl;return -1;}// 获取文档节点的 根节点 rootXMLElement *root = xmlDoc.RootElement();// 添加一些指定点for (int i = 0; i < 100; i++) {point p(0,  1);// 定义坐标元素节点 pointXMLElement *point = xmlDoc.NewElement("point");// 设置元素节点 point 的属性和值point->SetAttribute("x", p.x);point->SetAttribute("y", p.y);// 将元素节点 point 添加到根节点 root下root->InsertEndChild(point);}// 添加一些随机坐标点for (int i = 0; i < 100; i++) {point p(rand() * 0.001, rand() * 0.002);// 定义坐标元素节点 pointXMLElement *point = xmlDoc.NewElement("point");// 设置元素节点 point 的属性和值point->SetAttribute("x", p.x);point->SetAttribute("y", p.y);// 将元素节点 point 添加到根节点 root下root->InsertEndChild(point);}// 保存 xml 文件return xmlDoc.SaveFile(XMLPath);
}int modifyXML(const char *XMLPath) {// 文档节点XMLDocument xmlDoc;if (xmlDoc.LoadFile(XMLPath) != XML_SUCCESS) {cout << "The xml file is not exits" << endl;return -1;}// 获取 文档节点中的 root 根节点XMLElement *root = xmlDoc.RootElement();// 定义要修改的元素节点XMLElement *point = root->FirstChildElement("point");// 将所有 x 属性为 0 的 point 的 y 属性值都改为 2while (point != nullptr) {const char *x = point->Attribute("x");if (x && strcmp(x, "0") == 0) {point->SetAttribute("y", 2);cout << "modify done" << endl;}point = point->NextSiblingElement("point");}// 保存return xmlDoc.SaveFile(XMLPath);
}int deleteXML(const char *XMLPath) {// 文档节点XMLDocument xmlDoc;if (xmlDoc.LoadFile(XMLPath) != XML_SUCCESS) {cout << "The xml file is not exits" << endl;return -1;}// 获取 根节点 rootXMLElement *root = xmlDoc.RootElement();// 准备要被删除的元素XMLElement *point = root->FirstChildElement("point");while (point != nullptr) {const char *x = point->Attribute("x");// 删除 x 属性值 为 0 的 point 元素if (x && strcmp(x, "0") != 0) {point = point->NextSiblingElement("point");} else {XMLElement *delete_point = point;point = point->NextSiblingElement("point");root->DeleteChild(delete_point);cout << "delete done" << endl;}}// 保存return xmlDoc.SaveFile(XMLPath);
}void printXML(const char *XMLPath) {// 文档节点XMLDocument xmlDoc;if (xmlDoc.LoadFile(XMLPath) != XML_SUCCESS) {cout << "The xml file is not exits" << endl;return;}XMLPrinter printer;xmlDoc.Print(&printer);cout << printer.CStr() << endl;
}int main(int argc, char *argv[]) {srand(unsigned(time(NULL)));const char *filename = "MAP.xml";if(createXML(filename) != XML_SUCCESS){cout<<"Create xml file failed"<<endl;return 0;}if (addXML(filename) != XML_SUCCESS) {cout << "Add xml file failed" << endl;return 0;}if (modifyXML(filename) != XML_SUCCESS) {cout << "Modify xml file failed" << endl;return 0;}if (deleteXML(filename) != XML_SUCCESS) {cout << "Delete xml file failed" << endl;return 0;}printXML(filename);}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

尚品汇-sku存入Redis缓存(二十三)

目录&#xff1a; &#xff08;1&#xff09;分布式锁改造获取sku信息 &#xff08;2&#xff09;使用Redisson 分布式锁 AOP实现缓存 &#xff08;3&#xff09;定义缓存aop注解 &#xff08;1&#xff09;分布式锁改造获取sku信息 前面学习了本地锁的弊端&#xff0c;…

NFTScan 浏览器现已支持 .mint 域名搜索功能!

近日&#xff0c;NFT 数据基础设施 NFTScan 浏览器现已支持用户输入 .mint 域名进行 Mint Blockchain 网络钱包地址的搜索查询&#xff0c; NFTScan 用户能够轻松地使用域名追踪 NFT 交易&#xff0c;为 NFT 钱包地址相关的搜索查询功能增加透明度和便利性。 NFTScan explorer…

规划决策算法(四)---Frenet坐标系

知乎&#xff1a;坐标系转换 1.Frenet 坐标系 什么是 Frenet 坐标系&#xff1a; 为什么使用 Frenet 坐标系&#xff1a; 通常情况&#xff0c;我们只会关注车辆当前距离左右车道线的距离&#xff0c;来判断是否偏离车道&#xff0c;是否需要打方向盘进行方向微调。而不是基于…

腾讯云k8s相关

1.某个服务腾讯云内网地址&#xff1f; 比如&#xff1a;spiderflow-web正式环境&#xff1a;http://spiderflow-web.sd-backend:30001 试一试&#xff1a;

MongoDB教程(二十二):MongoDB固定集合

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、固定集…

FastGPT 源码调试配置

目录 一、添加 launch.json 文件 二、调试 本文简单介绍如何通过 vscode 对 FastGPT 进行调试。 这里假设已经安装 vsocde 和 FastGPT本地部署。 一、添加 launch.json 文件 vscode 打开 FastGPT 项目,点击 调试 -> 显示所有自动调试配置 -> 添加配置 -> Node.j…

通用网络验证系统,承载能力强,支持高并发、高承载、多线路

这个网络验证系统基于PhpMySql数据库架构的网络验证系统&#xff0c;安全稳定、性能强悍、 承载能力强&#xff0c;支持高并发、高承载、多线路&#xff0c;支持服务器集群架设,高性能设计&#xff0c;速度非常快&#xff0c;效率非常高。 客户端支持VC、VB、DELPHI、易语言、…

C++内存管理(候捷)第四讲 笔记

上中下三个classes分析 Loki allocator的三个类&#xff0c;从低阶到高阶分别为&#xff1a;Chunk, FixedAllocator, SmallObjAllocator Chunk&#xff1a;pData指针&#xff0c;指向分配的一个chunk&#xff0c;firstAvailableBlock_索引&#xff0c;指向第一个可用区块是第几…

自动导入unplugin-auto-import+unplugin-vue-components

文章介绍 接下来将会以Vite Vue3 TS的项目来举例实现 在我们进行项目开发时&#xff0c;无论是声明响应式数据使用的ref、reactive&#xff0c;或是各种生命周期&#xff0c;又或是computed、watch、watchEffect、provide-inject。这些都需要前置引入才能使用&#xff1a; …

基于PSO粒子群优化的GroupCNN分组卷积网络时间序列预测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 粒子群优化算法&#xff08;PSO&#xff09; 4.2 分组卷积神经网络&#xff08;GroupCNN&#xff09; 4.3 PSO优化GroupCNN 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行…

【已解决】Python ValueError: math domain error 详解

【已解决】Python ValueError: math domain error 详解 在Python编程中&#xff0c;遇到ValueError: math domain error是一个相对常见的问题。此错误通常表明传递给数学函数的参数超出了其定义域。本文将深入探讨此错误的根源、解决思路、具体解决方法、常见场景分析以及扩展…

【在Linux世界中追寻伟大的One Piece】Linux进程概念

目录 1 -> 冯诺依曼体系结构 2 -> 操作系统(operator System) 2.1 -> 概念 2.2 -> 系统调用和库函数 3 -> 进程 3.1 -> 概念 3.2 -> 进程-PCB 3.3 -> 进程状态 3.3.1 -> Z(Zombie)-僵尸进程 3.3.2 -> 孤儿进程 3.4 -> 进程优先级 …

五. TensorRT API的基本使用-TensorRT-network-structure

目录 前言0. 简述1. 案例运行2. 代码分析2.1 main.cpp2.2 model.cpp 总结下载链接参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习课程第五章—TensorRT API 的基本使用&#x…

Redisson分布式锁使用详解

引言 日常开发中&#xff0c;难免遇到一些并发的场景&#xff0c;为了保证接口执行的一致性&#xff0c;通常采用加锁的方式&#xff0c;因为服务是分布式部署模式&#xff0c;本地锁Reentrantlock和Synchnorized这些就先放到一边了&#xff0c;Redis的setnx锁存在无法抱保证原…

QT开发(QT的基本概述和环境的安装)

QT的概述 一.QT的介绍背景1.1 什么是QT1.2QT的发展史1.3 Qt支持的平台1.4QT版本1.5QT的优点1.6QT的应用场景 二.搭建QT开发环境2.1 QT的开发工具的下载2.2 QT环境变量配置 三.QT的三种基类四.QT Hello World程序4.1使用按钮实现4.1.1 代码方式实现4.1.2 可视化操作实现 一.QT的…

如何在vscode中对在服务器上多卡运行的bash脚本进行debug?

问题描述 使用vscode可以很方便地添加断点&#xff0c;进行代码调试。 在使用服务器时&#xff0c;我们的python代码通常是通过bash脚本来执行的&#xff0c;那么如何进行debug呢&#xff1f; 待运行的bash 脚本示例 前半段定义了一些参数&#xff0c;后半段是执行python代码…

数据结构的概念和术语

目录 一.前言 二.数据结构的基本概念 三.数据结构的术语 一.前言 数据结构是一门研究非数值计算的程序设计中计算机的操作对象以及它们之间的关系和操作的学科。数据结构的基本数据结构包括两部分&#xff0c;线性结构跟非线性结构。 二.数据结构的基本概念 数据结构主要包括…

压测实操--kafka broker压测方案

作者&#xff1a;九月 环境信息&#xff1a; 操作系统centos7.9&#xff0c;kafka版本为hdp集群中的2.0版本。 kafka broker参数 num.replica.fetchers&#xff1a;副本抓取的相应参数&#xff0c;如果发生ISR频繁进出的情况或follower无法追上leader的情况则适当增加该值&…

CTF ssrf 基础入门

0x01 引言 我发现我其实并不是很明白这个东西&#xff0c;有些微妙&#xff0c;而且记忆中也就记得Gopherus这个工具了&#xff0c;所以重新学习了一下&#xff0c;顺便记录一下吧 0x02 辨别 我们拿到一个题目&#xff0c;他的名字可能就是题目类型&#xff0c;但是也有可能…

划分型dp,CF 1935C - Messenger in MAC

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 1935C - Messenger in MAC 二、解题报告 1、思路分析 比较简单的思路是反悔贪心&#xff0c;这里不展开说了&#xff0c;来说一下dp的做法 由于式子里面带绝对值&#xff0c;很烦&#xff0c;我们将pair按…