RapidXml是指 XML DOM解析工具包,是一个快速的读写xml文件的库文件(hpp)。本文旨在提供RapidXml文件读写操作,以及对节点的增加、删除、编译提供一个测试用例,以免忘记。
#include "rapidxml.hpp"
#include "rapidxml_utils.hpp"
#include "rapidxml_print.hpp"
#include
#include
#include
其对应的xml文件如下所示:
25
fire
1.3.0
0.5
1
3 4 5
1
smoke
1.6.0
0.2
1
4
1
motionanalyze
1
1
#include "rapidxml.hpp"
#include "rapidxml_utils.hpp"
#include "rapidxml_print.hpp"
#include
#include
#include
#include
#include
void CreateXml(const std::string& XMLFileName)
{
//保存Annotation, 把识别结果写进xml
// DOM
rapidxml::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_pi
rapidxml::xml_node<>* root = doc.allocate_node(rapidxml::node_pi, doc.allocate_string("xml version='1.0' encoding='utf-8'"));
doc.append_node(root);
// node_comment
rapidxml::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_data
rapidxml::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 value
rapidxml::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_comment
rapidxml::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");
}
其结果如下图所示:
VOC2007
WriteExample.xml
nullptr
aware
1920
1080
3
0
首先是一些对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
#include
#include
#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< 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;
else
return;
//删除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* DeteNode = FunctionNode->first_node("Detectors");
if (DeteNode != nullptr)
{
for (rapidxml::xml_node* 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;
}
原始数据为:
25
fire
1.3.0
0.5
1
3 4 5
1
smoke
1.6.0
0.2
1
4
1
motionanalyze
1
1
修改后为:
Logitech
fire
1.3.0
0.5
1
smoke
1.6.0
0.2
1
4
1
感谢 https://www.cnblogs.com/MenAngel/p/11552588.html