对于配置文件,一般会选用ini,xml 等等的配置格式。如何快速高效的从文件内读取自己想要的信息是每个做配置文件想要达到的效果。对以小型开发我们并不用时用到msxml这种重量级的解析器。那样会给自己添麻烦的。这里我推荐大家使用rapidxml。
之前使用tinyxml 感觉还可以。后看了rapidxml 就想换用这个开源库。经常编写跨平台软件省去编译和加载lib。4个文件实现解析xml而且超高效官网还拿他跟strlen比较速度牛X吧看看下面的表。
其他废话我就不多讲。其实之前也有人介绍这个库怎么使用。这里我就给几个链接。
燕良博客:http://blog.csdn.net/Neil3D/archive/2010/03/11/5369173.aspx
官网:http://rapidxml.sourceforge.net/
如果不懂xml的概念的朋友自己到网上找下相关的教程学习下。这里我简单的介绍下各个文件的作用:自己留个底怕以后自己会忘。
库可以配置宏:
RAPIDXML_NO_EXCEPTIONS //不使用异常
RAPIDXML_STATIC_POOL_SIZE //内存池大小默认(64 * 1024)
一般都不用改
rapidxml.hpp:
只要文件 实现内存池 解析string 异常处理
xml_base 基数节点类
xml_attribute 文本类
xml_node 节点类
xml_document 文档类
rapidxml_iterators.hpp:
提供两个迭代器类:node_iterator, attribute_iterator
rapidxml_print.hpp:
提供跟字符串,流对象的装换函数
rapidxml_utils.hpp:
提供一个file用来读取文件使用
跟两个计数函数 count_children,count_attributes
节点类型源码讲的很清楚
- //! Enumeration listing all node types produced by the parser.
- //! Use xml_node::type() function to query node type.
- enum node_type
- {
- node_document, //!< A document node. Name and value are empty.
- node_element, //!< An element node. Name contains element name. Value contains text of first data node.
- node_data, //!< A data node. Name is empty. Value contains data text.
- node_cdata, //!< A CDATA node. Name is empty. Value contains data text.
- node_comment, //!< A comment node. Name is empty. Value contains comment text.
- node_declaration, //!< A declaration node. Name and value are empty. Declaration parameters (version, encoding and standalone) are in node attributes.
- node_doctype, //!< A DOCTYPE node. Name is empty. Value contains DOCTYPE text.
- node_pi //!< A PI node. Name contains target. Value contains instructions.
- };
简单操作:
- #include <iostream>
- #include <string>
- #include <rapidxml/rapidxml.hpp>
- #include <rapidxml/rapidxml_utils.hpp>
- #include <rapidxml/rapidxml_print.hpp>
- using namespace std;
- int main()
- {
- using namespace rapidxml;
- xml_document<> doc;
- xml_node<> *node = doc.allocate_node(node_element,"a","Google公司");
- doc.append_node(node);
- xml_attribute<> *attr = doc.allocate_attribute("href","google.com");
- node->append_attribute(attr);
- //直接输出
- cout<<"print:doc"<<doc<<endl;
- //用保存到string
- string strxml;
- print(std::back_inserter(strxml),doc,0);
- cout<<"print:strxml"<<strxml<<endl;
- //支持c风格的这里不演示,自己看文档吧
- return 0;
- }
运行结果:
读取文件(这里是从其他拷过来我刚学的时候就保存下来了,忘了在那里考的网上有好几个位兄弟都有的感觉,我也借来用用):
基本的步骤为
首先获取xml文件数据
然后分析数据
获取节点
获取属性
获取名字
获取值
...
代码如下:
- #include <iostream>
- #include <rapidxml/rapidxml.hpp>
- #include <rapidxml/rapidxml_utils.hpp>
- #include <rapidxml/rapidxml_print.hpp>
- using namespace rapidxml;
- int main()
- {
- file<> fdoc("config.xml");
- std::cout<<fdoc.data()<<std::endl;
- xml_document<> doc;
- doc.parse<0>(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;
- //! 修改之后再次保存
- xml_node<>* size = root->first_node("size");
- size->append_node(doc.allocate_node(node_element,"w","0"));
- size->append_node(doc.allocate_node(node_element,"h","0"));
- std::string text;
- rapidxml::print(std::back_inserter(text),doc,0);
- std::cout<<text<<std::endl;
- std::ofstream out("config.xml");
- out << doc;
- system("PAUSE");
- return EXIT_SUCCESS;
- }
- 生成的xml为:
- <?xml version='1.0' encoding='utf-8' ?>
- <config>
- <color>
- <red>0.1</red>
- <green>0.1</green>
- <blue>0.1</blue>
- <alpha>1.0</alpha>
- </color>
- <size>
- <x>640</x>
- <y>480</y>
- </size>
- <mode fullscreen="false">screen mode</mode>
- </config>
需要说明的是rapidxml明显有一个bug
那就是append_node(doc.allocate_node(node_element,"h","0"));的时候并不考虑该对象是否存在!