结论:rapidxml和pugixml在生成xml方面,我建议使用pugixml,优点很多,不用关心string的生命周期,像函数一样使用添加节点,属性,很方便;而且效率高,个人测试了下:生成300个xml文件,pugixml用时6s,rapidxml用时60+s,效率差了10倍

如果你工作必须使用rapidxml或者换起来麻烦,那么继续往下看,有关写xml需要注意的一些问题

rapidxml 下载:

在官网上下载即可,
http://rapidxml.sourceforge.net/
https://sourceforge.net/projects/rapidxml/

得到的压缩包里有文件如下:

读取或者解析xml,这篇大佬写的比较全面:
https://blog.csdn.net/v_xchen_v/article/details/75634273

这里补充下生成xml方面需要注意的问题:

1. 字符串的生命周期问题:每次添加节点,string需要使用rapidxml的内存申请函数

如果给节点赋值的是一个局部变量string或者char*,如果局部变量的生命周期,那么节点的值就会为空,建议使用rapidxml自带的allocate_string方法来申请字符串内存,这样它的生命周期和节点的值必然是一致的了;

2. 节点包含中文的情况(这部分个人理解,如有不对,恳请斧正)

先说我们要写的xml文件如下:

<book PageNumber="10"><name>小王子</name>
</book>

一般写的话,还有<?xml version="1.0" encoding="utf-8"?>,这是我们常见的,同样有 <?xml version="1.0" encoding="gbk"?>等,编码格式声明;
使用rapidxml,写入字符串,有char *wchar_t *的区别,默认是char *

   // char * 方式rapidxml::xml_node<>* rot = xml_doc.allocate_node(rapidxml::node_pi, xml_doc.allocate_string("xml version='1.0' encoding='gbk'"));// wchar_t * 方式rapidxml::xml_node<wchar_t>* rot = xml_doc.allocate_node(rapidxml::node_pi, xml_doc.allocate_string(L"xml version='1.0' encoding='utf-8'"));

如果你用的是char*,然后节点包含中文,这时候声明为:<?xml version="1.0" encoding="utf-8"?>,那么生成的xml文件在浏览器里会报错,如下所示:

所以这里建议:如果你用的是char*,然后节点包含中文,使用<?xml version="1.0" encoding="gbk"?>这个声明;
当然最好的,是用wchar_t *,节点包含中文,就可以使用<?xml version="1.0" encoding="utf-8"?>声明,不用担心编码解析问题

3. 节点写入int,float等类型的值

int, float,bool需要转换成char*字符串再写入节点,这里觉得使用不方便,不过还是提供下转换的函数如下,具体见下面代码里的Convert函数

char *方式创建一个包含中文格式的xml文件

#include <iostream>
#include <sstream>#include "rapidxml.hpp"
#include "rapidxml_utils.hpp"
#include "rapidxml_print.hpp"// int , float, double等类型 转为 std::string
// bool 类型会解析成 false:0, true :1
template <typename T>
std::string Convert(const T value)
{using namespace std;ostringstream oss;oss << value;string str(oss.str());return str;
}int main(int argc, char const *argv[])
{rapidxml::xml_document<>  xml_doc;//生成 <?xml version="1.0" encoding="utf-8"?>//创建指向上述节点位置的节点对象rapidxml::xml_node<>* rot = xml_doc.allocate_node(rapidxml::node_pi, xml_doc.allocate_string("xml version='1.0' encoding='gbk'"));xml_doc.append_node(rot);rapidxml::xml_node<>* root_node = xml_doc.allocate_node(rapidxml::node_element, xml_doc.allocate_string("book"));// 写入int, float等值需要先转成string类型再写入int count = 10;char *pageNum_str = xml_doc.allocate_string(Convert(count).c_str());rapidxml::xml_attribute<>* attr_pageNum = xml_doc.allocate_attribute(xml_doc.allocate_string("PageNumber"), pageNum_str);root_node->append_attribute(attr_pageNum);rapidxml::xml_node<>* name_node = xml_doc.allocate_node(rapidxml::node_element, xml_doc.allocate_string("name"), xml_doc.allocate_string("小王子"));root_node->append_node(name_node);xml_doc.append_node(root_node);// 先得到std::string sOut;rapidxml::print(std::back_inserter(sOut), xml_doc, 0);std::cout << sOut << std::endl;// 保存xml文件 std::string file_name("rapidxml_example.xml");// C++ 流式写入文件std::ofstream pagefile(file_name);pagefile << sOut;pagefile.close();return 0;
}

wchar_t方式创建一个包含中文格式的xml文件

#include <iostream>
#include <sstream>#include "rapidxml.hpp"
#include "rapidxml_utils.hpp"
#include "rapidxml_print.hpp"template <typename T>
std::wstring Convert(const T Num)
{using namespace std;wostringstream oss;oss << Num;wstring str(oss.str());return str;
}// std::wstring 转 std::string
std::string ws2s(const std::wstring &ws)
{size_t i;std::string curLocale = setlocale(LC_ALL, NULL);setlocale(LC_ALL, "chs");const wchar_t* _source = ws.c_str();size_t _dsize = 2 * ws.size() + 1;std::unique_ptr< char[] > buff(new char[_dsize]);memset(buff.get(), 0x0, _dsize);wcstombs_s(&i, buff.get(), _dsize, _source, _dsize);std::string result = buff.get();setlocale(LC_ALL, curLocale.c_str());return result;
}// std::string 转 std::wstring
std::wstring s2ws(const std::string &s)
{size_t i;std::string curLocale = setlocale(LC_ALL, NULL);setlocale(LC_ALL, "chs");const char* _source = s.c_str();size_t _dsize = s.size() + 1;std::unique_ptr< wchar_t[] > buff(new wchar_t[_dsize]);wmemset(buff.get(), 0x0, _dsize);mbstowcs_s(&i, buff.get(), _dsize, _source, _dsize);std::wstring result = buff.get();setlocale(LC_ALL, curLocale.c_str());return result;
}// using namespace std;
int main(int argc, char const *argv[])
{rapidxml::xml_document<wchar_t>  xml_doc;//生成 <?xml version="1.0" encoding="utf-8"?>//创建指向上述节点位置的节点对象rapidxml::xml_node<wchar_t>* rot = xml_doc.allocate_node(rapidxml::node_pi, xml_doc.allocate_string(L"xml version='1.0' encoding='utf-8'"));xml_doc.append_node(rot);rapidxml::xml_node<wchar_t>* root_node = xml_doc.allocate_node(rapidxml::node_element, xml_doc.allocate_string(L"book"));// 写入int, float等值需要先转成string类型再写入int count = 10;wchar_t *pageNum_str = xml_doc.allocate_string(Convert(count).c_str());rapidxml::xml_attribute<wchar_t>* attr_pageNum = xml_doc.allocate_attribute(xml_doc.allocate_string(L"PageNumber"), pageNum_str);root_node->append_attribute(attr_pageNum);rapidxml::xml_node<wchar_t>* name_node = xml_doc.allocate_node(rapidxml::node_element, xml_doc.allocate_string(L"name"), xml_doc.allocate_string(L"小王子"));root_node->append_node(name_node);xml_doc.append_node(root_node);// 先得到std::wstring sOut;rapidxml::print(std::back_inserter(sOut), xml_doc, 0);std::wcout.imbue(std::locale("chs"));std::wcout << sOut << std::endl;// 保存xml文件 std::string file_name("rapidxml_wchar_example.xml");// C 库函数写入文件,可以确保文件编码为utf-8std::wstring wfilename = s2ws(file_name);FILE * fp = _wfsopen(wfilename.c_str(), L"a+,ccs=UTF-8", _SH_DENYNO);if (fp == NULL){printf("err\n");}int num = fwprintf_s(fp, L"%s", sOut.c_str());fclose(fp);return 0;
}

rapidxml库生成xml小例子及需注意的问题相关推荐

  1. c++ 类文件的动态库生成及调用例子

    https://blog.csdn.net/josiechen/article/details/70174445 首先,创建一个简单的类,类头文件的名称与项目工程的名称应该一致, 控制台项目工程名:t ...

  2. android用XmlSerializer序列和DOM库生成相机标定所需的xml文件

    第一种:用XmlSerializer序列生成 XmlSerializer序列化的进行xml文件生成,先生成xml文件file,然后依次创建字段和属性.内容. 代码部分: XmlSerializer s ...

  3. 生成句法分析树以及从一个小例子来看词义消歧及语义角色标注

    一.生成句法分析树 把一句话按照句法逻辑组织成一棵树,由人来做这件事是可行的,但是由机器来实现是不可思议的,然而算法世界就是这么神奇,把一个十分复杂的过程抽象成仅仅几步操作,甚至不足10行代码,就能让 ...

  4. windows下dlib库简介、安装问题解决及简单小例子 (python)

    一.dlib简介 Dlib是一个现代C++框架,解决包含机器学习算法以及开发复杂软件的实现问题,它被广泛应用在工业和学术研究领域,包括机器人.嵌入式设备.移动手机以及大规模高性能计算环境中,DLib的 ...

  5. python(dict字典相关知识以及小例子:生成一个列表,存放100个随机整数,找出出现次数最多的数字)

    一.什么是字典? #字典的使用 #子字典是一个容器类,可以用来存储数据 #列表存储数据特点:1.有序的 2.每一个都有一个索引,通过索引可以对数据进行查询,修改,删除#字典存储数据: key:valu ...

  6. C++:通过多态实现接口并生成dll和lib文件的小例子

    1.接口声明头文件 首先声明一个形状基类,然后是三个派生类三角形.长方形和圆形. 基类中只有一个函数,getArea()输出面积 三个派生类分别对getArea()重载,分别有各自的构造函数 派生类的 ...

  7. 在Eclipse中写第一个hibernate小例子

    在hibernate自带的文档中,包含了一个很简单的小例子,不过这个小例子是基于ant的,而且说的不是很详细,不利于新手学习.在这里,我将在Eclipse中实现这个例子,并给出详细的实现步骤.     ...

  8. ​【Python基础】告别枯燥,60 秒学会一个 Python 小例子(文末下载)

    本文推荐一个python的傻瓜式的学习资源,内容简单易懂,让人可以在60 秒学会一个 Python 小例子 当前库已有 300多 个实用的小例子 本文来源:https://github.com/jac ...

  9. Gcc详解以及静态库、动态库生成

    [转] Gcc详解以及静态库.动态库生成 http://www.360doc.com/content/10/0619/14/1795182_33985297.shtml 1.gcc包含的c/c++编译 ...

  10. pyqt5菜鸟教程_PyQt5系列教程(61):PyQt5与数据库互联的小例子1

    今天我们一起来学习一下如何使用PyQt5与数据进行互联.当然如果你觉得使用PyQt5与数据库互联很麻烦,你也可以使用Python第三方库进行数据互联,达到你的目的就行了. 本次数据的数据库,我们选择的 ...

最新文章

  1. 查看docker 容器的ip地址
  2. jquery 移除border_jQuery - 删除元素
  3. 牛客 - 仓库选址(中位数+思维)
  4. spring-boot注解详解(一)
  5. java 使用jar_Java 使用JAR文件
  6. 【写作技巧】本科毕业论文开题报告写作攻略
  7. 利用CSS3 animation绘制动态卡通人物,无需使用JS代码
  8. MYSQL服务器my.cnf配置文档详解
  9. 超实用的浏览器插件json格式转换
  10. 表情识别相关论文摘要
  11. 搭建ASP环境-win7安装IIS并运行ASP程序
  12. 字节大幅压缩了22~23年的招聘
  13. 应用软件设计不是CRUD:如何进行应用系统功能模块的耦合性设计
  14. 车辆管理系统无法连接服务器,智能通道人员车辆管理软件常见问题
  15. bm算法好后缀 java实现_BM算法 | Depeng's Blog
  16. 教你高效修改文件夹名称,将首写字母改为大写
  17. PHP根据字符串拼音首字母进行排序/PHP通讯录按字母A-Z排序
  18. 笔记本外接显示屏模糊解决办法,调缩放比没用?
  19. 青蛙与蚊子(C++结构体练习题)
  20. 笨蛋去括号法求空集的幂集P(∅)和空集的幂集的幂集P({∅})和空集的幂集的幂集P(P({∅}))

热门文章

  1. ios 边录音边放_iOS 录音、音频的拼接剪切以及边录边压缩转码
  2. 使用uni-app开发App简易教程
  3. Python+Tensorflow+CNN实现车牌识别
  4. 电脑编程需要下载什么软件吗
  5. 出生就遇浏览器大战,亲爹还不爱,命运坎坷的JavaScript终于苦尽甘来
  6. 大数据视频资源——尚硅谷大数据视频地址
  7. 天勤数据结构代码——树基本操作
  8. 《OpenCV 4.5计算机视觉开发实战(基于VC++)》示例代码免费下载
  9. f2fs学习笔记 - 3. F2FS文件系统布局
  10. 计算机领域车牌识别,城市智慧停车的智能眼睛——车牌识别系统