C++ xml 解析器
C++的xml解析器有很多,这个知乎回答里有一个列表:https://www.zhihu.com/question/32046606
下面使用其中的RapidXml试试。
官方地址: https://link.zhihu.com/?target=http%3A//rapidxml.sourceforge.net/
Manual地址:http://rapidxml.sourceforge.net/manual.html
这里有个例子:https://www.cnblogs.com/lancidie/p/3304089.html
上面代码是在ubuntun下是编译不过的,我作了小的更改:
编译环境:Ubuntu 16.04 、 gcc version 5.4.0
下载了上面rapidxml 1.13版本,这个版本在此环境下,仍需要打一个补丁,其实就是在rapidxml_print.hpp开头加了以下几行声明,放在类内部开始即可。
template<class OutIt, class Ch> inline OutIt print_children(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch> inline OutIt print_element_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch> inline OutIt print_data_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch> inline OutIt print_cdata_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch> inline OutIt print_declaration_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch> inline OutIt print_comment_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch> inline OutIt print_doctype_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch> inline OutIt print_pi_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
整个代码如下:
#include "rapidxml/rapidxml.hpp"
#include "rapidxml/rapidxml_print.hpp"
#include "rapidxml/rapidxml_utils.hpp" #include <string>
#include <iostream>
#include <fstream> using namespace rapidxml;
using namespace std; void WriteXml1()
{
xml_document<> doc;
xml_node<>* rot = doc.allocate_node(rapidxml::node_pi,doc.allocate_string("xml version='1.0' encoding='utf-8'"));
doc.append_node(rot);
xml_node<>* node = doc.allocate_node(node_element,"config",NULL);
xml_node<>* color = doc.allocate_node(node_element,"color",NULL);
doc.append_node(node);
node->append_node(color);
color->append_node(doc.allocate_node(node_element,"red","0.1"));
color->append_node(doc.allocate_node(node_element,"green","0.1"));
color->append_node(doc.allocate_node(node_element,"blue","0.1"));
color->append_node(doc.allocate_node(node_element,"alpha","1.0")); xml_node<>* size = doc.allocate_node(node_element,"size",NULL);
size->append_node(doc.allocate_node(node_element,"x",""));
size->append_node(doc.allocate_node(node_element,"y",""));
node->append_node(size); xml_node<>* mode = doc.allocate_node(rapidxml::node_element,"mode","screen mode");
mode->append_attribute(doc.allocate_attribute("fullscreen","false"));
node->append_node(mode); std::string text;
rapidxml::print(std::back_inserter(text), doc, ); std::cout<<text<<std::endl; std::ofstream out("config.xml");
out << doc;
} void WriteXml2()
{
xml_document<> doc; //是解析器
char a[] = "<top>"//如果单独传, 就不能加上xml的头部信息,
//否则会报错
"<name>tangqiang</name>"
"<age>22</age>"
"</top>";
char* p = a;
doc.parse<>(p); xml_node<>* node = doc.first_node();//去顶级结点
cout << (node->name())<< endl;
node = node->first_node();
while (node) {
cout << node->name() << node->value() << endl;//name() value()返回的字符串不会去掉首尾的空白字符
node = node->next_sibling();
} ofstream out("test.xml");//ofstream 默认时,如果文件存在则会覆盖原来的内容,不存在则会新建
out << doc;//doc 这样输出时在目标文件中不会有xml 头信息---<?xml version='1.0' encoding='utf-8' >
out.close();
} void ReadXml()
{
file<> fdoc("config.xml");
std::cout<<fdoc.data()<<std::endl;
xml_document<> doc;
doc.parse<>(fdoc.data()); std::cout<<doc.name()<<std::endl; //! 获取根节点
xml_node<>* root = doc.first_node();
std::cout<<root->name()<<std::endl; //! 获取根节点第一个节点
xml_node<>* node1 = root->first_node();
std::cout<<node1->name()<<std::endl; xml_node<>* node11 = node1->first_node();
std::cout<<node11->name()<<std::endl;
std::cout<<node11->value()<<std::endl; //! 添加之后再次保存
//需要说明的是rapidxml明显有一个bug
//那就是append_node(doc.allocate_node(node_element,"h","0"));的时候并不考虑该对象是否存在!
xml_node<>* size = root->first_node("size");
size->append_node(doc.allocate_node(node_element,"w",""));
size->append_node(doc.allocate_node(node_element,"h","")); std::string text;
rapidxml::print(std::back_inserter(text),doc,); std::cout<<text<<std::endl; std::ofstream out("config.xml");
out << doc;
} void DeleteXml()
{
file<> fdoc("config.xml");
xml_document<> doc;
doc.parse<>(fdoc.data()); std::string text;
rapidxml::print(std::back_inserter(text), doc, );
std::cout<<text<<std::endl; xml_node<>* root = doc.first_node(); xml_node<>* sec = root->first_node(); root->remove_node(sec); //移除根节点下的sec结点(包括该结点下所有结点)
text="删除一个节点\r\n";
rapidxml::print(std::back_inserter(text), doc, );
std::cout<<text<<std::endl; root->remove_all_nodes(); //移除根节点下所有结点
text="删除所有节点\r\n";
rapidxml::print(std::back_inserter(text), doc, );
std::cout<<text<<std::endl; std::ofstream out("test.xml");
out<<doc;
} void EditXml()
{
file<> fdoc("config.xml");
std::cout<<fdoc.data()<<std::endl;
xml_document<> doc;
doc.parse<>(fdoc.data()); std::cout<<doc.name()<<std::endl; //! 获取根节点
xml_node<>* root = doc.first_node();
xml_node<>* delnode = root->first_node("color");
root->remove_node(delnode);//先删除address节点
//
xml_node<>* lnode = root->first_node("size");//找到post节点
xml_node<>* mynode=doc.allocate_node(node_element,"address","河北");
root->insert_node(lnode,mynode); std::string text;
rapidxml::print(std::back_inserter(text),doc,); std::cout<<text<<std::endl; std::ofstream out("version.xml");
out << doc;
} void TravelsalXml()
{
file<> fdoc("config.xml");
//std::cout<<fdoc.data()<<std::endl;
xml_document<> doc;
doc.parse<>(fdoc.data()); //std::cout<<doc.name()<<std::endl; //! 获取根节点
xml_node<>* root = doc.first_node(); for(rapidxml::xml_node<char> * node = root->first_node();
node != NULL;
node = node->next_sibling())
{
std::cout<<(node->name())<<" "<<(node->value())<<endl;
} std::cout<<"travesal from size node"<<std::endl;
for(rapidxml::xml_node<char> * node = root->first_node("size");
node != NULL;
node = node->next_sibling())
{
std::cout<<(node->name())<<" "<<(node->value())<<endl;
}
} void TravelsalAttrXml()
{
file<> fdoc("config.xml");
xml_document<> doc;
doc.parse<>(fdoc.data()); //! 获取根节点
xml_node<>* root = doc.first_node();
xml_node<>* subroot = root->first_node("mode"); for(rapidxml::xml_attribute<char> * attr = subroot->first_attribute("fullscreen");
attr != NULL;
attr = attr->next_attribute())
{
//char * value = attr->value(); cout<<(attr->name())<<" "<<(attr->value())<<endl;
}
} int main()
{
//WriteXml1();
//WriteXml2();
//ReadXml();
//DeleteXml();
//EditXml(); //TravelsalXml();
TravelsalAttrXml(); return ;
}
总结:以上代码演示了写XML、读XML、删除某一个节点、遍历所有的节点、遍历所有的属性。
RapidXml可以说,使用起来非常方便。
C++ xml 解析器的更多相关文章
- Duilib源码分析(三)XML解析器—CMarkup
上一节介绍了控件构造器CDialogBuilder,接下来将分析其XML解析器CMarkup: CMarkup:xml解析器,目前内置支持三种编码格式:UTF8.UNICODE.ASNI,默认为UTF ...
- tinyxml一个优秀的C++ XML解析器
读取和设置xml配置文件是最常用的操作,试用了几个C++的XML解析器,个人感觉TinyXML是使用起来最舒服的,因为它的API接口和Java的十分类似,面向对象性很好. TinyXML是一个开源的解 ...
- TinyXML:一个优秀的C++ XML解析器
//-------------------------------------------------------------------------------------------------- ...
- 转:TinyXM--优秀的C++ XML解析器
读取和设置xml配置文件是最常用的操作,试用了几个C++的XML解析器,个人感觉TinyXML是使用起来最舒服的,因为它的API接口和Java的十分类似,面向对象性很好. TinyXML是一个开源的解 ...
- XML解析器(转)
常见C/C++ XML解析器有tinyxml.XERCES.squashxml.xmlite.pugxml.libxml等等,这些解析器有些是支持多语言的,有些只是单纯C/C++的.如果你是第一次接触 ...
- XML 解析器
所有现代浏览器都内建了供读取和操作 XML 的 XML 解析器.解析器把 XML 转换为 XML DOM 对象 - 可通过 JavaScript 操作的对象. 解析 XML 文档为DOM对象 方法一: ...
- TinyXML:一个优秀的C++ XML解析器[转]
TinyXML:一个优秀的C++ XML解析器 读取和设置xml配置文件是最常用的操作,试用了几个C++的XML解析器,个人感觉TinyXML是使用起来最舒服的,因为它的API接口和Java的十分类似 ...
- Java XML解析器
使用Apache Xerces解析XML文档 一.技术概述 在用Java解析XML时候,一般都使用现成XML解析器来完成,自己编码解析是一件很棘手的问题,对程序员要求很高,一般也没有专业厂商或者开源组 ...
- Xml的转义字符--约束-xml解析器
XML解析器:Dom适合增删改查(crud),缺点就是内存消耗大: Sax:内存消耗非常小,解析速度快,但是不适合增删改:
- CDATA(不应由XML解析器进行解析的文本数据)、CDATA的使用场景
1.1. CDATA: CDATA(Unparsed Character Data)指的是不应由XML解析器进行解析的文本数据. 因为XML解析器会将“<”(新元素的开始)和“&”(字符 ...
随机推荐
- 微信小程序 之wx.getLocation()获取地理信息中的小坑
提到wx.getLocation()这个方法,大家都知道是获取地理信息的 今天用这个方法获取定位经纬度后传给后台取得附近markers标记集合, 在开发工具上都正常有标记出现 ,但是在手机测试时,死活 ...
- jvm类加载的过程
java类加载过程:加载-->验证-->准备-->解析-->初始化,之后类就可以被使用了.绝大部分情况下是按这 样的顺序来完成类的加载全过程的.但是是有例外的地方,解析也是可以 ...
- Jena+fuseki
1.下载apache-jena-3.1.0.tar.gz,这个可以将ttl三元组文件或者xml文件加载 进入bin目录,执行./tdbloader2 --loc /path/for/database ...
- iOS -- SKTextureAtlas类
SKTextureAtlas类 继承自 NSObject 符合 NSCodingNSObject(NSObject) 框架 /System/Library/Frameworks/SpriteKi ...
- 现代数字信号处理——AR模型
1. AR模型概念观 AR模型是一种线性预测,即已知N个数据,可由模型推出第N点前面或后面的数据(设推出P点),所以其本质类似于插值,其目的都是为了增加有效数据,只是AR模型是由N点递推, ...
- 电话号码 【trie树】
电话号码 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描写叙述 给你一些电话号码,请推断它们是否是一致的,即是否有某个电话是还有一个电话的前缀. 比方: Emerg ...
- Git以及github的使用方法(六),管理修改
现在,假定你已经完全掌握了暂存区的概念.下面,我们要讨论的就是,为什么Git比其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件. 你会问,什么是修改?比如你新增了一行,这就是一个修改 ...
- 如何使用电骡eMule上传资源
1 在电脑中创建一个文件夹专门为上传资源使用 在里面放入任意文件并右击显示ED2K链接 链接效果如下 2 登陆verycd网站,并点击上传资源 复制ED2K地址并选择分类
- 2.nginx整合PHP
/usr/local/src/下都有什么:.tar.gz文件和解压之后的源码 /usr/local/下都有什么:源码编译之后的东西 安装mysql客户端 安装mysql服务端 启动mysql服务端 s ...
- mysqldump导入导出详解
mysqldump可以指定路径的,如果没指定路径,而只写了文件名的话,那么就在当前进入mysql命令行所在的目录,也就是mysql安装目录下 mysqldump --default-characte ...