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

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);}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【进阶篇-Day12:JAVA中stream流、File类的介绍】
  • python每日学习:numpy库的用法(上)
  • .net 连接达梦数据库开发环境部署
  • 线性代数重要知识点和理论(下)
  • SpringBoot-21 SpringBoot微服务的发布与部署(3种方式)
  • photoshop学习笔记——移动工具
  • ROS参数服务器增删改查实操Python
  • 网络安全常见错误及解决办法(更新中)
  • 数据结构——单链表OJ题(下)
  • Golang | Leetcode Golang题解之第279题完全平方数
  • UE5 C++跑酷练习(Part2)
  • paraFoam 运行 报错 usr/lib/x86_64-linux-gnu/libQt5Core.so 已解决
  • 将git默认的编辑器设置为vin
  • springboot3-web-questions-分析
  • flink 实现大数据实时数据采集
  • 2018一半小结一波
  • angular组件开发
  • JavaWeb(学习笔记二)
  • Linux链接文件
  • 半理解系列--Promise的进化史
  • 简单实现一个textarea自适应高度
  • 警报:线上事故之CountDownLatch的威力
  • 盘点那些不知名却常用的 Git 操作
  • 前端js -- this指向总结。
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 十年未变!安全,谁之责?(下)
  • 说说动画卡顿的解决方案
  • 通过git安装npm私有模块
  • 一文看透浏览器架构
  • Java总结 - String - 这篇请使劲喷我
  • (19)夹钳(用于送货)
  • (C#)if (this == null)?你在逗我,this 怎么可能为 null!用 IL 编译和反编译看穿一切
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (Qt) 默认QtWidget应用包含什么?
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (四)鸿鹄云架构一服务注册中心
  • (一)认识微服务
  • (译)2019年前端性能优化清单 — 下篇
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • ***汇编语言 实验16 编写包含多个功能子程序的中断例程
  • .“空心村”成因分析及解决对策122344
  • .DFS.
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .NET6实现破解Modbus poll点表配置文件
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理
  • ??javascript里的变量问题
  • @media screen 针对不同移动设备
  • [ Algorithm ] N次方算法 N Square 动态规划解决
  • [4.9福建四校联考]
  • [acwing周赛复盘] 第 69 场周赛20220917
  • [AI Google] Ask Photos: 使用Gemini搜索照片的新方法