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解析器会将“<”(新元素的开始)和“&”(字符 ...
随机推荐
- PHP基础知识练习
1 . PHP 指的是?(C ) A.Private Home Page B.Personal Hypertext Processor C.PHP: Hypertext Preprocessor D. ...
- 数据结构自己实现——Tree and Forest
//中D序??遍???历???二t叉?树??? //先??序??遍???历???二t叉?树??? //后??序??遍???历???二t叉?树??? #include <iostream> ...
- Network | sk_buff
sk_buff结构可能是linux网络代码中最重要的数据结构,它表示接收或发送数据包的包头信息.它在中定义,并包含很多成员变量供网络代码中的各子系统使用. 这个结构被不同的网络层(MAC或者其他 ...
- 在spring中使用数据库
若要在spring中使用数据库,首先需要配置数据源. 1.使用数据源连接池,可以使用DBCP(Data Base Connection Pooling) <bean id="datas ...
- 东方14模拟赛之noip2015/day1/3/神奇的幻方
总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 128000kB 描述 幻方是一种很神奇的N*N 矩阵:它由数字 1,2,3, … …,N*N 构成,且每行.每列及 ...
- Wannafly挑战赛16
E(pbds) 题意: 1<=m,n<=5e5 分析: 首先指向关系形成了一个基环外向树森林 实际上我们可以完全不用真正的去移动每个球,而只需要在计数的时候考虑考虑就行了 对于树上的情况, ...
- 小W计树
排列组合思想. 先跑一遍最短路, 再从1节点开始搜索, 假如搜到一个点的路径长度等于最短路, 则记录到达该点的路径数 + 1. 最后遍历一遍, ans *= rec[i] 输出答案即可. 关键在于想到 ...
- 求助大神!怎样除去XML节点反复的值的数据
<?xml version="1.0" encoding="utf-8"? > <UpdCfg> <Upgrade> < ...
- H2数据库集群
H2数据库集群 1. H2数据库简单介绍 1.1 H2数据库优势 经常使用的开源数据库:H2,Derby,HSQLDB.MySQL,PostgreSQL. 当中H2,HSQLDB相似,十分适合作为嵌入 ...
- ListView 自己定义BaseAdapter实现单选打勾(无漏洞)
(假设须要完整demo,请评论留下邮箱) (眼下源代码已经不发送.假设须要源代码,加qq316701116.不喜勿扰) 近期由于一个项目的原因须要自己定义一个BaseAdapter实现ListVIew ...