RapidXml是指 XML DOM解析工具包,是一个快速的读写xml文件的库文件(hpp)。本文旨在提供RapidXml文件读写操作,以及对节点的增加、删除、编译提供一个测试用例,以免忘记。

1. 读取XML

#include "rapidxml.hpp"
#include "rapidxml_utils.hpp"
#include "rapidxml_print.hpp"
#include <vector>
#include <string>
#include <map>
#include <set>
#include <iostream>
#include <sstream>
#include <io.h>void str2int(int& int_tmp, const std::string& string_tmp)
{std::stringstream stream(string_tmp);stream >> int_tmp;
}void str2float(float& float_tmp, const std::string& string_tmp)
{float_tmp = atof(string_tmp.c_str());
}void splitLabels(const std::string& labels, std::vector<std::string>& splitalbelres)
{std::string result;std::stringstream input(labels);while (input >> result){splitalbelres.push_back(result);}
}void readFunctionParam(rapidxml::xml_node<char>* FunctionNode)
{rapidxml::xml_node<char>* DeteNode = FunctionNode->first_node("Detectors");if (DeteNode != nullptr){for (rapidxml::xml_node<char>* node = DeteNode->first_node("iter"); node != nullptr; node = node->next_sibling()){std::string name = "";std::string version = "";std::string label = "";float fConfidence = 0.0;int    iShowWin = 0;int iIsStandard = 0;std::set<int> setUsefulLabel;rapidxml::xml_node<>* pName = node->first_node("name");if (pName != nullptr){name = pName->value();}rapidxml::xml_node<>* pVersion = node->first_node("version");if (pVersion != nullptr){version = pVersion->value();}rapidxml::xml_node<>* pConf = node->first_node("confidence");if (pConf != nullptr){str2float(fConfidence, pConf->value());}rapidxml::xml_node<>* pShowWin = node->first_node("bshowDebugWin");if (pShowWin != nullptr){str2int(iShowWin, pShowWin->value());}rapidxml::xml_node<>* pIsStandard = node->first_node("bStandard");if (pIsStandard != nullptr){str2int(iIsStandard, pIsStandard->value());}rapidxml::xml_node<>* pUsefulLabel = node->first_node("usefulLabel");if (pUsefulLabel != nullptr){label = pUsefulLabel->value();std::vector<std::string> splitlabelres;splitLabels(label, splitlabelres);for (int i = 0; i < splitlabelres.size(); i++){setUsefulLabel.insert(std::atoi(splitlabelres[i].c_str()));}}}rapidxml::xml_node<char>* pShowreportNode = FunctionNode->first_node("ShowReportWin");if (pShowreportNode != nullptr){int iShowReportWin = 0;str2int(iShowReportWin, pShowreportNode->value());}}
}void ReadParam(const rapidxml::xml_document<>& pDoc)
{//获取根节点rapidxml::xml_node<char>* root = pDoc.first_node("config");//找到采样帧率节点int iSampleFrequency;rapidxml::xml_node<>* samplefre = root->first_node("SampleFrequency");str2int(iSampleFrequency, samplefre->value());//找到功能节点std::string sFunctionName = "SMOKEFireDetection";rapidxml::xml_node<>* intrusion = root->first_node(sFunctionName.c_str());if (intrusion != nullptr){readFunctionParam(intrusion);}}void readXMLByFile(const std::string& xmlpath)
{/************************************************************************file类data()               返回 char* 的xml文本内容size()             返回 unsigned int的文本数据长度定义:               rapidxml::file<0> valName("xmlpath");xml_document类parse(Ch *text)       将文本数据解析为DOM treeclear()             清空DOM tree定义:               rapidxml::xml_document<0> doc;************************************************************************/try{// 用file文件读入缓冲区rapidxml::file<> fdoc(xmlpath.c_str());// 打印从文件中读取的内容std::cout << fdoc.data();// 解析获取DOM实例rapidxml::xml_document<> doc;doc.parse<0>(fdoc.data());ReadParam(doc);doc.clear();}catch (rapidxml::parse_error e){std::cout << e.what() << std::endl;return;}}static const int buf_len = 2048;
static char buf[buf_len] = { 0 };
void readXMLByStream(const std::string& xmlpath)
{try{// 清空缓冲区memset(buf, 0, buf_len);// 判断文件是否存在if (_access(xmlpath.c_str(), 0) == -1){std::cout << "xml file " << xmlpath << "is not exits!" << std::endl;return;}// 实例化文件读取流std::ifstream infile(xmlpath, std::ios::in);if (!infile){std::cout << "file stream instance error!" << std::endl;return;}// 读取文件内容到缓冲区infile.read(buf, buf_len);// 输出文件内容std::cout << buf << std::endl;// 实例化DOMrapidxml::xml_document<> doc;doc.parse<0>(buf);ReadParam(doc);doc.clear();infile.close();}catch (rapidxml::parse_error e){std::cout << e.what() << std::endl;return;}}void main()
{std::string xmlpath = "ReadExample.xml";readXMLByFile(xmlpath);readXMLByStream(xmlpath);std::system("pause");}

其对应的xml文件如下所示:

<config>
<SampleFrequency>25</SampleFrequency><SMOKEFireDetection><Detectors><iter><name>fire</name><version>1.3.0</version><confidence>0.5</confidence><bshowDebugWin>1</bshowDebugWin><usefulLabel>3 4 5</usefulLabel><bStandard>1</bStandard></iter><iter><name>smoke</name><version>1.6.0</version><confidence>0.2</confidence><bshowDebugWin>1</bshowDebugWin><usefulLabel>4</usefulLabel><bStandard>1</bStandard></iter><iter><name>motionanalyze</name><version></version><confidence></confidence><bshowDebugWin>1</bshowDebugWin><usefulLabel></usefulLabel></iter></Detectors><ShowReportWin>1</ShowReportWin>
</SMOKEFireDetection></config>

2. 创建XML文件

#include "rapidxml.hpp"
#include "rapidxml_utils.hpp"
#include "rapidxml_print.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <io.h>
#include <stdlib.h>void CreateXml(const std::string& XMLFileName)
{//保存Annotation, 把识别结果写进xml// DOMrapidxml::xml_document<> doc;// node_declaration//rapidxml::xml_node<>* declaration = doc.allocate_node(rapidxml::node_declaration);//declaration->append_attribute(doc.allocate_attribute("version", "1.0"));//declaration->append_attribute(doc.allocate_attribute("encoding", "utf-8"));//doc.append_node(declaration);// node_pirapidxml::xml_node<>* root = doc.allocate_node(rapidxml::node_pi, doc.allocate_string("xml version='1.0' encoding='utf-8'"));doc.append_node(root);// node_commentrapidxml::xml_node<>* comment = doc.allocate_node(rapidxml::node_comment, 0, " 这是对目标的Annotation保存格式 ");doc.append_node(comment);// node_element rapidxml::xml_node<>* node = doc.allocate_node(rapidxml::node_element, "annotation", "information");doc.append_node(node);// node_datarapidxml::xml_node<>* folder = doc.allocate_node(rapidxml::node_element, "folder", "VOC2007");node->append_node(folder);rapidxml::xml_node<>* filename = doc.allocate_node(rapidxml::node_element, "filename", XMLFileName.c_str());node->append_node(filename);// node_element with valuerapidxml::xml_node<>* source = doc.allocate_node(rapidxml::node_element, "source", nullptr);source->append_node(doc.allocate_node(rapidxml::node_element, "database", "My VOC2007 Databas"));source->append_node(doc.allocate_node(rapidxml::node_element, "annotation", "VOC2007"));source->append_node(doc.allocate_node(rapidxml::node_element, "image", "flickr"));source->append_node(doc.allocate_node(rapidxml::node_element, "flickrid", "nullptr"));node->append_node(source);rapidxml::xml_node<>* owner = doc.allocate_node(rapidxml::node_element, "owner", nullptr);owner->append_node(doc.allocate_node(rapidxml::node_element, "flickrid", "nullptr"));owner->append_node(doc.allocate_node(rapidxml::node_element, "name", "aware"));node->append_node(owner);rapidxml::xml_node<>* size = doc.allocate_node(rapidxml::node_element, "size", nullptr);int width = 1920;char cw[128];_itoa_s(width, cw, 128, 10);size->append_node(doc.allocate_node(rapidxml::node_element, "width", cw));int height = 1080;char ch[128];_itoa_s(height, ch, 128, 10);size->append_node(doc.allocate_node(rapidxml::node_element, "height", ch));size->append_node(doc.allocate_node(rapidxml::node_element, "depth", "3"));node->append_node(size);rapidxml::xml_node<>* segmented = doc.allocate_node(rapidxml::node_element, "segmented", "0");node->append_node(segmented);for (int i = 0; i < 2; i++){// node_commentrapidxml::xml_node<>* comment = doc.allocate_node(rapidxml::node_comment, 0, " 目标的位置状态信息 ");node->append_node(comment);rapidxml::xml_node<>* object = doc.allocate_node(rapidxml::node_element, "object", nullptr);node->append_node(object);object->append_node(doc.allocate_node(rapidxml::node_element, "name", doc.allocate_string("example")));object->append_node(doc.allocate_node(rapidxml::node_element, "pose", "Unspecified"));object->append_node(doc.allocate_node(rapidxml::node_element, "truncated", "0"));object->append_node(doc.allocate_node(rapidxml::node_element, "difficult", "0"));rapidxml::xml_node<>* bndbox = doc.allocate_node(rapidxml::node_element, "bndbox", nullptr);object->append_node(bndbox);bndbox->append_node(doc.allocate_node(rapidxml::node_element, "xmin", "11"));bndbox->append_node(doc.allocate_node(rapidxml::node_element, "ymin", "20"));bndbox->append_node(doc.allocate_node(rapidxml::node_element, "xmax", "1000"));bndbox->append_node(doc.allocate_node(rapidxml::node_element, "ymax", "600"));//打印整个XML内容std::string text;rapidxml::print(std::back_inserter(text), doc, 0);std::cout << text << std::endl;}//打印整个XML内容std::string text;rapidxml::print(std::back_inserter(text), doc, 0);std::cout << text << std::endl;// 输出DOM到文件std::ofstream outfile(XMLFileName.c_str(), std::ios::out);   //ofstream默认时,如果文件存在则覆盖原来的内容,不存在则新建if (outfile){outfile << doc;outfile.close();}doc.clear();
}void main()
{const std::string Xmlfilename = "WriteExample.xml";CreateXml(Xmlfilename);std::system("pause");}

其结果如下图所示:

<?xml version='1.0' encoding='utf-8' ?>
<!--这是对目标的Annotation保存格式-->
<annotation><folder>VOC2007</folder><filename>WriteExample.xml</filename><source><database>My VOC2007 Databas</database><annotation>VOC2007</annotation><image>flickr</image><flickrid>nullptr</flickrid></source><owner><flickrid>nullptr</flickrid><name>aware</name></owner><size><width>1920</width><height>1080</height><depth>3</depth></size><segmented>0</segmented><!--目标的位置状态信息 --><object><name>example</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>11</xmin><ymin>20</ymin><xmax>1000</xmax><ymax>600</ymax></bndbox></object><!--目标的位置状态信息 --><object><name>example</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>11</xmin><ymin>20</ymin><xmax>1000</xmax><ymax>600</ymax></bndbox></object>
</annotation>

3. 修改及增加删除

首先是一些对xml的节点解释:
xml_node类
1)node_type type() const; 获取结点类型 获取的类型是枚举的
2)Ch* name() const; 获取结点名
3)std::size_t name_size() const; 获取结点名长度
4)Ch* value() const; 获取结点值
5)std::size_t value_size() const; 获取结点值长度
6)xml_node* first_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 获取DOM Tree第一个子结点的指针
第一个参数为节点名,如果给定第一个参数为”a”, 则该函数寻找结点名为a的第一个子结点;第二个参数为结点名长度
7)xml_node* last_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 获取DOM Tree最后一个子结点的指针
参数含义同上
8)xml_attribute* first_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 获取结点的第一个属性指针
9)xml_attribute* next_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 获取结点的下一个属性指针
10)xml_attribute* last_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 获取结点的最后一个属性指针
11)xml_node* previous_sibling(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 获取上一个同级结点的指针
12)xml_node* next_sibling(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 获取下一个同级结点的指针
13)xml_attribute* first_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 获取第一个同级结点的指针
14)xml_attribute* last_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 获取最后一个同级结点的指针
15)void insert_node(xml_node< Ch > *where, xml_node< Ch > *child); 在第一个参数指向的结点之前,插入一个结点
xml_attribute类
1)xml_attribute *previous_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 获取前一个属性
2)xml_attribute *next_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const;获取后一个属性

#include <iostream>
#include <string>
#include <fstream>
#include "string.h"
#include "rapidxml.hpp"
#include "rapidxml_print.hpp"
#include "rapidxml_utils.hpp"void modifyXML(const char * file_name)
{std::string text;//用file解析DOM时必须是绝对路径rapidxml::file<> fdoc(file_name);//打印读取的文件std::cout<<fdoc.data();rapidxml::xml_document<> doc;doc.parse<0>(fdoc.data());//取得根节点rapidxml::xml_node<>* root = doc.first_node("config");//删除第一个元素if (root->first_node() != nullptr)root->remove_first_node();text = "\r\n移除根节点下的第一个元素节点\r\n";rapidxml::print(std::back_inserter(text), doc, 0);       //doc内容输出到text尾处std::cout << text << std::endl;rapidxml::xml_node<>* FunctionNode = root->first_node("SMOKEFireDetection");if (FunctionNode != nullptr)std::cout << "SMOKEFireDetection is not null" << std::endl;elsereturn;//删除FunctionNode节点的最后一个元素if (FunctionNode->last_node() != nullptr)FunctionNode->remove_last_node();text = "\r\n移除根节点下的FunctionNode的最后一个元素节点\r\n";rapidxml::print(std::back_inserter(text), doc, 0);std::cout << text << std::endl;rapidxml::xml_node<char>* DeteNode = FunctionNode->first_node("Detectors");if (DeteNode != nullptr){for (rapidxml::xml_node<char>* node = DeteNode->first_node("iter"); node != nullptr; node = node->next_sibling()){rapidxml::xml_node<>* pName = node->first_node("name");if (pName != nullptr && std::string(pName->value()) == "fire"){//移除根节点下的FunctionNode结点下第一个循环节点下的bStandardNode节点rapidxml::xml_node<> *bStandardNode = node->first_node("bStandard");if (bStandardNode != nullptr){node->remove_node(bStandardNode);}//移除根节点下的FunctionNode结点下第一个循环节点下的的usefulLabelNode节点rapidxml::xml_node<> *usefulLabelNode = node->first_node("usefulLabel");if (usefulLabelNode != nullptr){node->remove_node(usefulLabelNode);}text = "\r\n移除根节点下的FunctionNode结点下第一个循环节点下的bStandardNode节点和usefulLabelNode节点\r\n";rapidxml::print(std::back_inserter(text), doc, 0);std::cout << text << std::endl;continue;}else if (pName != nullptr && std::string(pName->value()) == "motionanalyze"){//移除根节点下的FunctionNode结点下第三个循环节点下的所有节点DeteNode->remove_node(node);break;}}}text = "\r\n移除根节点下的FunctionNode结点下第三个循环节点下的所有节点\r\n";rapidxml::print(std::back_inserter(text), doc, 0);std::cout << text << std::endl;//在FunctionNode的Detectors节点处插入一个KeyBorad节点rapidxml::xml_node<>* Graphics = FunctionNode->first_node("Detectors");//找到Graphics节点rapidxml::xml_node<>* new_node = doc.allocate_node(rapidxml::node_element, "KeyBorad", "Logitech");new_node->append_attribute(doc.allocate_attribute("Interface", "USB"));FunctionNode->insert_node(Graphics, new_node);text = "\r\n在FunctionNode的Detectors节点下面插入一个KeyBorad节点\r\n";rapidxml::print(std::back_inserter(text), doc, 0);std::cout << text << std::endl;写入文件std::ofstream out("1.xml");out << doc;
}int main()
{const char *file_name = "E:\\VS2015Project\\ReadXmlWriteXml\\ReadXmlWriteXml\\RapidExample.xml";modifyXML(file_name);std::system("pause");return 0;
}

原始数据为:

<config>
<SampleFrequency>25</SampleFrequency><SMOKEFireDetection><Detectors><iter><name>fire</name><version>1.3.0</version><confidence>0.5</confidence><bshowDebugWin>1</bshowDebugWin><usefulLabel>3 4 5</usefulLabel><bStandard>1</bStandard></iter><iter><name>smoke</name><version>1.6.0</version><confidence>0.2</confidence><bshowDebugWin>1</bshowDebugWin><usefulLabel>4</usefulLabel><bStandard>1</bStandard></iter><iter><name>motionanalyze</name><version></version><confidence></confidence><bshowDebugWin>1</bshowDebugWin><usefulLabel></usefulLabel></iter></Detectors><ShowReportWin>1</ShowReportWin>
</SMOKEFireDetection></config>

修改后为:

<config><SMOKEFireDetection><KeyBorad Interface="USB">Logitech</KeyBorad><Detectors><iter><name>fire</name><version>1.3.0</version><confidence>0.5</confidence><bshowDebugWin>1</bshowDebugWin></iter><iter><name>smoke</name><version>1.6.0</version><confidence>0.2</confidence><bshowDebugWin>1</bshowDebugWin><usefulLabel>4</usefulLabel><bStandard>1</bStandard></iter></Detectors></SMOKEFireDetection>
</config>

感谢 https://www.cnblogs.com/MenAngel/p/11552588.html

rapidxml 文件读写,增加删除节点相关推荐

  1. iPhone开发中现文件的增加 删除和查询

    iPhone开发中,我们常常用到一些对于文件的增加,删除和查询,这些基本的功能对于开发者来说非常的重要,而且非常实用.本文给大家介绍一下如何实现这几个具体的功能. //创建文件 -(void)Crea ...

  2. 【Elasticsearch】es 增加 删除 节点

    文章目录 1.概述 2.添加节点 3.删除节点 3.1 方案一停启集群分片自动分配 本文为博主九师兄(QQ:541711153 欢迎来探讨技术)原创文章,未经允许博主不允许转载. 1.概述 2.添加节 ...

  3. 掌控板iis服务器文件读写,iis 设置网站文件夹或文件读写 编辑 删除权限

    我这个是抄的别人,害怕那个网站挂掉,所以在这里记录下,以上内容均来自:http://www.longshannet.com/ne... 近日在调试网站过程中需要用到,对网站某个文件夹或文件 设置读写 ...

  4. linux将用户删除文件,linux 用户配制文件 用户增加及删除 以及用户属于的更改...

    1.用户密码文件 /etc/passwd root  :   x   :    0    :       0    :          root      :     /root    :    / ...

  5. solr-cloud 集群动态增加、删除节点

    本次讲述动态增加节点基于上一章集群搭建的基础上来讲:https://blog.csdn.net/u013490585/article/details/86494476 上一章的例子中用了3台zk,4台 ...

  6. Linux增加/删除文件权限

    Linux增加/删除文件权限 ubuntu系统中,对于不同用户及不同用户组中用户对文件的操作权限都不相同,通过控制台我们可以快速的对文件权限进行操作. 对于修改权限可以使用两种方案来更改其权限,下面认 ...

  7. python导入文件列行_python读写csv文件并增加行列的实例代码

    python读写csv文件并增加行列,具体代码如下所示: # -*- coding: utf-8 -*- """ Created on Thu Aug 17 11:28: ...

  8. DistCp迁移Hive数据过程中源集群增加删除文件等场景测试

    1 概述   由于在数据迁移过程中,上层任务仍在运行,会出现源集群新增文件及删除文件的情况,因此进行测试 2 需要同步的数据文件说明   源集群:192.168.40.100:8020,目标集群:19 ...

  9. 在VB中INI文件的读写、删除(对中文支持很好)

    很多时候我们编一个程序不一定要用到注册表来保存设置(如果说一个程序没有设置就不算好程序了).INI是一个很好的选择.有人说,Savesetting是一个不错的选择,但是我了解到,不能永久的保存(起码在 ...

  10. JS监听页面元素删除子节点、增加子节点、修改子节点的内容

    监听这个事件DOMSubtreeModified. 表示如果当前监听元素的子节点有改动:包括删除子节点.增加子节点.修改子节点的内容,都会触发这个事件. var container = documen ...

最新文章

  1. NSDictionary、NSMutableDictionary基本使用
  2. DeepLearning tutorial(1)Softmax回归原理简介+代码详解
  3. CTFshow 命令执行 web122
  4. c 连接mysql后 怎么用_使用C语言连接mysql,并进行操作
  5. RabbitMQ消息
  6. 解密Go协程的栈内存管理
  7. 编程指南_halide编程技术指南(连载一)
  8. c++自学笔记 7.15
  9. jmeter(十六)配置元件之计数器
  10. ctfshow-WEB-web3
  11. Hadoop各组件详解
  12. 万年历显示c语言百度文库,C语言万年历
  13. 【强档推荐】动漫初音未来Ⅱ主题
  14. C#反射基础知识实例总结
  15. OSError: [Errno 1] Operation not permitted: '/tmp/pip-g3bg0s-uninstall/System/Library/Frameworks/Pyt
  16. Markdown学习
  17. python+selenium实战搭建PO模型
  18. 企业邮箱怎么注册流程?企业邮箱域名怎么注册?
  19. JDK异常处理No appropriate protocol
  20. 照片损坏怎么办,怎么恢复受损照片

热门文章

  1. 模糊控制 之 模糊集,隶属函数,模糊关系
  2. 那么如何成为优秀的机械工程师,如何提升自己的实力,有哪些值得注意和学习的呢?
  3. 20200827 plecs blockset更新版本
  4. 高程(DEM) ASCII数据获取
  5. linux centos 网易云音乐,Centos7.4安装网易云音乐教程
  6. 医院所用到的信息系统的缩写、定义,持续更新
  7. ubuntu前置耳机孔没声音的解决办法
  8. VGG16网络参数细节
  9. 我的世界java版游戏图标_minecraftpe JAVA版游戏包mod
  10. python判断键盘输入_python实时检测键盘输入函数的示例