目录

1. github 地址

2. 使用

3. 解析xml demo

4. 注意点

5. 解析效果展示

6.创建xml

7.创建xml效果展示

8. 完整的示例,添加Vector

9. 参考


1. github 地址

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

2. 使用

直接把里面的 “tinyxml2.h” 和 “tinyxml2.cpp” 加到自己工程,使用include "tinyxml2.h" 头文件就好

3. 解析xml demo

xml内容如下:

<?xml version="1.0" encoding="utf-8"?>
<annotation><folder>UAV_data</folder><filename>NG0_202303032032377079.xml</filename><size><width>3070</width><height>1600</height><depth>3</depth></size><segmented>0</segmented><object><name>round</name><location>0</location><diffcult>0</diffcult><diffcultt>3</diffcultt><bndbox><xmin>1405</xmin><ymin>1237</ymin><xmax>1628</xmax><ymax>1421</ymax></bndbox></object><object><name>long</name><diffcult>0</diffcult><location>0</location><bndbox><xmin>2337</xmin><ymin>1225</ymin><xmax>2580</xmax><ymax>1405</ymax></bndbox></object>
</annotation>

代码如下:

#include <iostream>
#include"tinyxml2.h"
using namespace std;
using namespace tinyxml2;void decodeXml(std::string xmlPath)
{//声明XMLDocument xml;string value, text;//导入xml文件if (xml.LoadFile(xmlPath.c_str()) != XML_SUCCESS){return;}//判断头文件是否为空XMLElement* rootNode = xml.RootElement();if (rootNode == NULL){return;}XMLElement* surface = rootNode->FirstChildElement("object");while (surface){XMLElement* surfaceChild = surface->FirstChildElement();while (surfaceChild){// surfaceChild->Value() 是获取节点的名称value = surfaceChild->Value();if (value == "bndbox"){XMLElement* bndboxChild = surfaceChild->FirstChildElement();// 因为bndbox节点里面又是节点,所以需要进行循环以及找NextSiblingElementwhile (bndboxChild){value = bndboxChild->Value();text = bndboxChild->GetText();bndboxChild = bndboxChild->NextSiblingElement();std::cout << value << ": " << text << std::endl;}}else{text = surfaceChild->GetText();std::cout << value << ": " << text << std::endl;}surfaceChild = surfaceChild->NextSiblingElement();}surface = surface->NextSiblingElement();}}int main()
{decodeXml("Z:/temp/cppSaveXml/NG0_202303032032377079.xml");return 0;
}

4. 注意点

1. 整体的逻辑其实就是一层一层的遍历,先找到需要遍历的那个节点,然后通过while和NextSiblingElement来进行循环;

2. surfaceChild->Value() 是获取节点的名称,如果 <name>round</name> 得到的是name。这里需要注意的就是,如果节点里面又有节点,这个时候就不能用 surfaceChild->GetText() 来获取里面的值,因为里面是节点,不是单纯的值,如果仍然使用GetText()会报错。
这个时候就需要用FirstChildElement() 这个方法来获取里面第一个节点的内容,然后再通过while进行循环遍历,如下

if (value == "bndbox")
{XMLElement* bndboxChild = surfaceChild->FirstChildElement();// 因为bndbox节点里面又是节点,所以需要进行循环以及找NextSiblingElementwhile (bndboxChild){value = bndboxChild->Value();text = bndboxChild->GetText();bndboxChild = bndboxChild->NextSiblingElement();}
}

3. 总的来说,就是一层一层递归,递归的时候需要判断是否是单节点还是里面还包含节点

5. 解析效果展示

6.创建xml

逻辑就是创建一个根节点,然后再依次创建子节点,然后子节点的 text 属性值设置,然后再把属性值与对应的子节点绑定,然后子节点在与根节点绑定

需要创建如下xml:

<?xml version="1.0" encoding="utf-8"?>
<annotation><filename>NG0_202303032032377079.xml</filename><size><width>3070</width><height>1600</height><depth>3</depth></size><object><name>round</name><bndbox><xmin>1405</xmin><ymin>1237</ymin><xmax>1628</xmax><ymax>1421</ymax></bndbox></object><object><name>long</name><bndbox><xmin>2337</xmin><ymin>1225</ymin><xmax>2580</xmax><ymax>1405</ymax></bndbox></object>
</annotation>

创建代码如下:

XMLElement* getNeedNode(XMLDocument& xml, const char* nodeName, const char* nodeText)
{XMLElement* node = xml.NewElement(nodeName);XMLText* node_text = xml.NewText(nodeText);node->InsertFirstChild(node_text);return node;
}void encode()
{XMLDocument xml;// 插入声明XMLDeclaration* declaration = xml.NewDeclaration();xml.InsertFirstChild(declaration);// 插入根节点XMLElement* rootNode = xml.NewElement("annotation");xml.InsertEndChild(rootNode);/*------------------新建一个filename节点--------------------------*/XMLElement* filename = xml.NewElement("filename");// 设置节点中的值XMLText* filename_text = xml.NewText("NG0_202303032032377079.xml");// 把节点中的值与filename节点链接起来filename->InsertFirstChild(filename_text);// 将 filename 节点与根节点绑定起来rootNode->InsertEndChild(filename);/*------------------新建一个size节点--------------------------*/XMLElement* size = xml.NewElement("size");/*------------------新建一个width节点--------------------------*/XMLElement* width = xml.NewElement("width");XMLText* width_text = xml.NewText("3070");width->InsertFirstChild(width_text);/*------------------新建一个height节点--------------------------*/XMLElement* height = xml.NewElement("height");XMLText* height_text = xml.NewText("1600");height->InsertFirstChild(height_text);/*------------------新建一个depth节点--------------------------*/XMLElement* depth = xml.NewElement("depth");XMLText* depth_text = xml.NewText("3");depth->InsertFirstChild(depth_text);// 将 width,height,depth 与 size 节点绑在一起size->InsertEndChild(width);size->InsertEndChild(height);size->InsertEndChild(depth);/*------------------新建第一个object节点--------------------------*/XMLElement* object = xml.NewElement("object");XMLElement* name = xml.NewElement("name");XMLText* name_text = xml.NewText("round");name->InsertFirstChild(name_text);XMLElement* bndbox = xml.NewElement("bndbox");// getNeedNode 方法为啥是引用,因为是要同一个 XMLDocument 这样才可以绑定, 所以传引用XMLElement* xmin = getNeedNode(xml, "xmin", "1405");XMLElement* ymin = getNeedNode(xml, "ymin", "1237");XMLElement* xmax = getNeedNode(xml, "xmax", "1628");XMLElement* ymax = getNeedNode(xml, "ymax", "1421");bndbox->InsertEndChild(xmin);bndbox->InsertEndChild(ymin);bndbox->InsertEndChild(xmax);bndbox->InsertEndChild(ymax);object->InsertEndChild(name);object->InsertEndChild(bndbox);rootNode->InsertEndChild(object);/*------------------新建第二个object节点--------------------------*/object = xml.NewElement("object");name = xml.NewElement("name");name_text = xml.NewText("long");name->InsertFirstChild(name_text);bndbox = xml.NewElement("bndbox");xmin = getNeedNode(xml, "xmin", "2337");ymin = getNeedNode(xml, "ymin", "1225");xmax = getNeedNode(xml, "xmax", "2580");ymax = getNeedNode(xml, "ymax", "1405");bndbox->InsertEndChild(xmin);bndbox->InsertEndChild(ymin);bndbox->InsertEndChild(xmax);bndbox->InsertEndChild(ymax);object->InsertEndChild(name);object->InsertEndChild(bndbox);rootNode->InsertEndChild(object);xml.SaveFile("Z:/temp/cppSaveXml/temp.xml");}int main()
{encode();return 0;
}

7.创建xml效果展示

8. 完整的示例,添加Vector

生成xml,使用传入vector,然后循环遍历vector

#include <iostream>
#include <vector>
#include <string>
#include"tinyxml2.h"
//#include "xmlNode.h"using namespace tinyxml2;struct Node
{int imageW;int imageH;int channel = 3;int xmin;int ymin;int xmax;int ymax;std::string label;float prob;Node(int in_w, int in_h, int in_xmin, int in_ymin, int in_xmax, int in_ymax, std::string in_label, float in_prob){imageW = in_w;imageH = in_h;xmin = in_xmin;ymin = in_ymin;;xmax = in_xmax;;ymax = in_ymax;;label = in_label;;prob = in_prob;;}
};void decodeXml(std::string xmlPath)
{//声明XMLDocument xml;std::string value, text;//导入xml文件if (xml.LoadFile(xmlPath.c_str()) != XML_SUCCESS){return;}//判断头文件是否为空XMLElement* rootNode = xml.RootElement();if (rootNode == NULL){return;}XMLElement* filename = rootNode->FirstChildElement("filename");const char* getFileName = filename->GetText();std::cout << getFileName << std::endl;XMLElement* surface = rootNode->FirstChildElement("object");while (surface){XMLElement* surfaceChild = surface->FirstChildElement();while (surfaceChild){// surfaceChild->Value() 是获取节点的名称value = surfaceChild->Value();if (value == "bndbox"){XMLElement* bndboxChild = surfaceChild->FirstChildElement();// 因为bndbox节点里面又是节点,所以需要进行循环以及找NextSiblingElementwhile (bndboxChild){value = bndboxChild->Value();text = bndboxChild->GetText();bndboxChild = bndboxChild->NextSiblingElement();std::cout << value << ": " << text << std::endl;}}else{text = surfaceChild->GetText();std::cout << value << ": " << text << std::endl;}surfaceChild = surfaceChild->NextSiblingElement();}surface = surface->NextSiblingElement();}}XMLElement* getNeedNode(XMLDocument& xml, const char* nodeName, const char* nodeText)
{XMLElement* node = xml.NewElement(nodeName);XMLText* node_text = xml.NewText(nodeText);node->InsertFirstChild(node_text);return node;
}void encodeXml(const char* inSaveXmlDir, int inW, int inH, std::vector<Node> inAllNode)
{XMLDocument xml;// 插入声明XMLDeclaration* declaration = xml.NewDeclaration();xml.InsertFirstChild(declaration);// 插入根节点XMLElement* rootNode = xml.NewElement("annotation");xml.InsertEndChild(rootNode);/*------------------新建一个filename节点--------------------------*/XMLElement* filename = xml.NewElement("filename");// 设置节点中的值XMLText* filename_text = xml.NewText(inSaveXmlDir);// 把节点中的值与filename节点链接起来filename->InsertFirstChild(filename_text);// 将 filename 节点与根节点绑定起来rootNode->InsertEndChild(filename);/*------------------新建一个size节点--------------------------*/XMLElement* size = xml.NewElement("size");/*------------------新建一个width节点--------------------------*/XMLElement* width = xml.NewElement("width");XMLText* width_text = xml.NewText(std::to_string(inW).c_str());width->InsertFirstChild(width_text);/*------------------新建一个height节点--------------------------*/XMLElement* height = xml.NewElement("height");XMLText* height_text = xml.NewText(std::to_string(inH).c_str());height->InsertFirstChild(height_text);/*------------------新建一个depth节点--------------------------*/XMLElement* depth = xml.NewElement("depth");XMLText* depth_text = xml.NewText("3");depth->InsertFirstChild(depth_text);// 将 width,height,depth 与 size 节点绑在一起size->InsertEndChild(width);size->InsertEndChild(height);size->InsertEndChild(depth);rootNode->InsertEndChild(filename);rootNode->InsertEndChild(size);/*------------------新建第一个object节点--------------------------*/for (auto node : inAllNode){XMLElement* object = xml.NewElement("object");XMLElement* name = xml.NewElement("name");XMLText* name_text = xml.NewText(node.label.c_str());name->InsertFirstChild(name_text);XMLElement* bndbox = xml.NewElement("bndbox");// getNeedNode 方法为啥是引用,因为是要同一个 XMLDocument 这样才可以绑定, 所以传引用XMLElement* xmin = getNeedNode(xml, "xmin", std::to_string(node.xmin).c_str());XMLElement* ymin = getNeedNode(xml, "ymin", std::to_string(node.ymin).c_str());XMLElement* xmax = getNeedNode(xml, "xmax", std::to_string(node.xmax).c_str());XMLElement* ymax = getNeedNode(xml, "ymax", std::to_string(node.ymax).c_str());bndbox->InsertEndChild(xmin);bndbox->InsertEndChild(ymin);bndbox->InsertEndChild(xmax);bndbox->InsertEndChild(ymax);object->InsertEndChild(name);object->InsertEndChild(bndbox);rootNode->InsertEndChild(object);}xml.SaveFile(inSaveXmlDir);}int main()
{const char* saveXmlDir = "Z:/temp/cppSaveXml/1.xml";std::vector<Node> allNode;Node nodeOne = { 1, 2, 3, 4, 5, 6, "1", 0.1 };Node nodeTwo = { 1, 2, 3, 4, 5, 6, "2", 0.1 };allNode.push_back(nodeOne);allNode.push_back(nodeTwo);encodeXml(saveXmlDir, 3070, 1600, allNode);return 0;
}

效果展示

9. 参考

1. C++解析XML文件_c++ xml解析_时·风·人的博客-CSDN博客

C++ 使用 tinyxml2 解析创建 xml相关推荐

  1. xml的学习和使用python解析读取xml文件

    1. XML的介绍 XML 指可扩展标记语言(EXtensible Markup Language). 和json类似也是用于存储和传输数据,还可以用作配置文件. 类似于HTML超文本标记语言,但是H ...

  2. C++ 本地使用tinyxml2解析Xml文件

    1.基本介绍 TinyXML2是一个开源.简单.小巧.高效的C++ XML解析器,它只有一个.h文件和一个.cpp文件组成,可以轻松集成到其它程序中.非常方便我们使用c++对xml进行处理. 可以读取 ...

  3. VC++ MSXML创建XML文件以及对XML文档解析

    VC++ MSXML创建XML文件以及对XML文档解析 转自http://www.newxing.com/Tech/Program/Cpp/703.html // XmlCreationDemo.cp ...

  4. Android -- 创建XML文件对象及其序列化, pull解析XML文件

    1. 创建XML文件对象及其序列化 示例代码:(模拟以xml格式备份短信到SD卡) SmsInfo.java, bean对象 /*** 短信的业务bean* @author Administrator ...

  5. Dom4j解析Xml文件,Dom4j创建Xml文件

    Dom4j解析Xml文件,Dom4j创建Xml文件 >>>>>>>>>>>>>>>>>>&g ...

  6. C++使用TinyXml2解析Xml

    1. TinyXml2 简介 TinyXml 一直是一个非常好用的 Xml 解析工具 , 最新的开源版本 TinyXml2 相对于旧版本的 TinyXml 使用更少的内存 , 更快 , 并且使用更少的 ...

  7. TinyXML-2解析XML数据

    声明 本文例子源自在C++中使用TinyXML2解析xml一文,其余部分来源于网络搜集,难免疏漏,敬请随意吐槽. XML以及JSON 什么是XML 根据Wikipedia-XML的说法: 可扩展标记语 ...

  8. dom4j解析xml,dom4j创建xml

    dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的.dom4j是一个非常非常优秀的Java XML API,具有性能优异.功能强大和极端易用使用的特点,同时它也是一个开放源 ...

  9. 创建xml并解析xml_构建,解析和提取XML

    创建xml并解析xml 学到更多. 开发更多. 连接更多. 新的developerWorks Premium会员计划可通过Safari图书在线获得对强大的开发工具和资源的无障碍访问权,其中包括500个 ...

最新文章

  1. python爬取小说章节信息用pygame进行数据显示_爬虫不过如此(python的Re 、Requests、BeautifulSoup 详细篇)...
  2. js中match、replace方法中使用正则表达式
  3. android 只输入数字与小数点_Android金额输入框只允许输入小数点后两位效果
  4. java float什么类型数据类型_Java中的Float和double数据类型
  5. 开发者究竟想从云中得到什么?
  6. java中aotomicInteger_面试官:你说一下对Java中的volatile的理解吧!
  7. 每日一技|活锁,也许你需要了解一下
  8. python pycharm 无法import win32api、win32con、win32com、win32gui 问题一次解决!方法合集
  9. 安卓原生系统_安卓原生系统为什么比MIUI和EMUI等国产系统更流畅
  10. u3d canvas设置
  11. python中 f代表什么_python 中下拉框中的f,v,m是什么意思??
  12. focus和onfocus区别
  13. JDBC Mybatis 调用 ORACLE 存储过程 函数 返回 varray 类型 function return varray out varray
  14. access_stratum_release version
  15. 一张30年前的大学排行榜!
  16. python entry_tkinter常用控件演示(Entry)
  17. 王阳明心学:此心光明,夫复何言
  18. 计算机选择题在线,计算机考试选择题
  19. 系统架构师设计培训心得之二——架构设计
  20. 即席查询(Ad Hoc)如何做到又快又稳?

热门文章

  1. ubuntu创建ssh密钥
  2. ubuntu18.04系统笔记本电脑合盖后无法唤醒问题解决
  3. 《面试补习》-熔断降级我学会了!
  4. WhatsApp营销正在大幅度影响你的订单量
  5. 10月数字资产项目评级更新|链塔评级
  6. [原创]双硬盘四系统安装全功略
  7. python 内存溢出_Python之内存泄漏和内存溢出
  8. 使命召唤,从此刻开始
  9. 管理系统的用户角色权限
  10. 音响分频器有什么作用