• RapidXml用法


    一、写xml 文件

    #include <iostream>
    #include "rapidxml/rapidxml.hpp"
    #include "rapidxml/rapidxml_utils.hpp"
    #include "rapidxml/rapidxml_print.hpp"
    
    using namespace rapidxml;
    
    int main()
    {    
    	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","information");  
    	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","640"));
    	size->append_node(doc.allocate_node(node_element,"y","480"));
    	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, 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>


    写文件样例2:

    #include <string>
    #include <iostream>
    #include <fstream>
    #include "rapidxml/rapidxml.hpp"
    #include "rapidxml/rapidxml_utils.hpp"
    #include "rapidxml/rapidxml_print.hpp"
    
    
    using namespace rapidxml;
    using namespace std;
    
    int main(int argc, char* argv[])
    {
    
        xml_document<> doc; //是解析器
        char a[] = "<top>"//假设单独传, 就不能加上xml的头部信息,
                   //否则会报错
                   "<name>tangqiang</name>"
                   "<age>22</age>"
                   "</top>";
        char* p = a;
        doc.parse<0>(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();
    	system("pause");
        return 0;
    }

    生成的xml例如以下

    <top>
    	<name>tangqiang</name>
    	<age>22</age>
    </top>
    


    二、读取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;
    
        //! 加入之后再次保存
        //须要说明的是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","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为

    <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>
    		<w>0</w>
    		<h>0</h>
    	</size>
    	<mode fullscreen="false">screen mode</mode>
    </config>


    三、删除节点

    #include "rapidxml/rapidxml.hpp"
    #include "rapidxml/rapidxml_utils.hpp"
    #include "rapidxml/rapidxml_print.hpp"
    
    #include<iostream>
    using namespace rapidxml;
    
    int main()
    {
    	file<> fdoc("config.xml");
    	xml_document<> doc;
    	doc.parse<0>(fdoc.data());
    
    	std::string text;  
    	rapidxml::print(std::back_inserter(text), doc, 0);  
    	std::cout<<text<<std::endl; 
    
    	xml_node<>* root = doc.first_node();
    
    	xml_node<>* sec = root->first_node();
    
    	root->remove_node(sec); //移除根节点下的sec结点(包含该结点下全部结点)
    	text="删除一个节点
    ";  
    	rapidxml::print(std::back_inserter(text), doc, 0);  
    	std::cout<<text<<std::endl; 
    
    	root->remove_all_nodes(); //移除根节点下全部结点
    	text="删除全部节点
    ";  
    	rapidxml::print(std::back_inserter(text), doc, 0);  
    	std::cout<<text<<std::endl; 
    
    	std::ofstream out("test.xml");
    	out<<doc;
    	system("pause");
    	return 0;
    }

    输出信息例如以下:

    <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>
    		<w>0</w>
    		<h>0</h>
    	</size>
    	<mode fullscreen="false">screen mode</mode>
    </config>
    
    
    删除一个节点
    
    <config>
    	<size>
    		<x>640</x>
    		<y>480</y>
    		<w>0</w>
    		<h>0</h>
    	</size>
    	<mode fullscreen="false">screen mode</mode>
    </config>
    
    
    删除全部节点
    
    <config/>
    


    四、编辑节点信息

    临时找到的编辑方法就是先删除再添加

    #include "rapidxml/rapidxml.hpp"
    #include "rapidxml/rapidxml_utils.hpp"
    #include "rapidxml/rapidxml_print.hpp"
    
    #include<iostream>
    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();
    	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,0);
    
    
    	std::cout<<text<<std::endl;
    
    	std::ofstream out("version.xml");
    	out << doc;
    	system("pause");
    	return 0;   
    }

    输出例如以下:

    <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>
    
    		<w>0</w>
    
    		<h>0</h>
    
    	</size>
    
    	<mode fullscreen="false">screen mode</mode>
    
    </config>
    
    
    
    
    
    <config>
    	<address>河北</address>
    	<size>
    		<x>640</x>
    		<y>480</y>
    		<w>0</w>
    		<h>0</h>
    	</size>
    	<mode fullscreen="false">screen mode</mode>
    </config>

    五、遍历全部节点

    for(rapidxml::xml_node<char> * node = parent_node->first_node("node name");
        node != NULL;
        node = node->next_sibling())
    {
        ...
    }
    

    六、遍历全部属性

    for(rapidxml::xml_attribute<char> * attr = node->first_attribute("node name");
        attr != NULL;
        attr = attr->next_attribute())
    {
        char * value = attr->value();
    }


    七、gcc使用-std=gnu++0x 编译rapidxml时会报错,错误信息大概例如以下

    ...rapidxml_print.hpp:120:23: error:

    call to function 'print_element_node' thatis neither visible in the

    template definition nor found byargument-dependent lookup

    out = print_element_node(out, node, flags,indent);

    ^

    ...rapidxml_print.hpp:242:22: note:

    'print_element_node' should be declaredprior to the call site or in

    namespace 'rapidxml'

    inline OutIt print_element_node(OutIt out,const xml_node<Ch> ...

    在这里找到了解决方法。

    经查,原来print_node()函数被其它函数调用,但在却没有定义(在被调用函数后定义了),所以解决方法为把print_node()函数移到print_children(), print_element_node() 等函数的后面。在原定义处就留一个函数声明即可。

    详细diff文件例如以下。

    Index: rapidxml_print.hpp
    ===================================================================
    --- rapidxml_print.hpp	(revision 2025)
    +++ rapidxml_print.hpp	(revision 2080)
    @@ -101,68 +101,9 @@
     
             ///////////////////////////////////////////////////////////////////////////
             // Internal printing operations
    -    
    -        // Print node
    +        
             template<class OutIt, class Ch>
    -        inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
    -        {
    -            // Print proper node type
    -            switch (node->type())
    -            {
    -
    -            // Document
    -            case node_document:
    -                out = print_children(out, node, flags, indent);
    -                break;
    -
    -            // Element
    -            case node_element:
    -                out = print_element_node(out, node, flags, indent);
    -                break;
    -            
    -            // Data
    -            case node_data:
    -                out = print_data_node(out, node, flags, indent);
    -                break;
    -            
    -            // CDATA
    -            case node_cdata:
    -                out = print_cdata_node(out, node, flags, indent);
    -                break;
    -
    -            // Declaration
    -            case node_declaration:
    -                out = print_declaration_node(out, node, flags, indent);
    -                break;
    -
    -            // Comment
    -            case node_comment:
    -                out = print_comment_node(out, node, flags, indent);
    -                break;
    -            
    -            // Doctype
    -            case node_doctype:
    -                out = print_doctype_node(out, node, flags, indent);
    -                break;
    -
    -            // Pi
    -            case node_pi:
    -                out = print_pi_node(out, node, flags, indent);
    -                break;
    -
    -                // Unknown
    -            default:
    -                assert(0);
    -                break;
    -            }
    -            
    -            // If indenting not disabled, add line break after node
    -            if (!(flags & print_no_indenting))
    -                *out = Ch('
    '), ++out;
    -
    -            // Return modified iterator
    -            return out;
    -        }
    +        inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);        
             
             // Print children of the node                               
             template<class OutIt, class Ch>
    @@ -372,7 +313,69 @@
                 *out = Ch('>'), ++out;
                 return out;
             }
    +        
    +        // Print node
    +        template<class OutIt, class Ch>
    +        inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
    +        {
    +            // Print proper node type
    +            switch (node->type())
    +            {
     
    +            // Document
    +            case node_document:
    +                out = print_children(out, node, flags, indent);
    +                break;
    +
    +            // Element
    +            case node_element:
    +                out = print_element_node(out, node, flags, indent);
    +                break;
    +            
    +            // Data
    +            case node_data:
    +                out = print_data_node(out, node, flags, indent);
    +                break;
    +            
    +            // CDATA
    +            case node_cdata:
    +                out = print_cdata_node(out, node, flags, indent);
    +                break;
    +
    +            // Declaration
    +            case node_declaration:
    +                out = print_declaration_node(out, node, flags, indent);
    +                break;
    +
    +            // Comment
    +            case node_comment:
    +                out = print_comment_node(out, node, flags, indent);
    +                break;
    +            
    +            // Doctype
    +            case node_doctype:
    +                out = print_doctype_node(out, node, flags, indent);
    +                break;
    +
    +            // Pi
    +            case node_pi:
    +                out = print_pi_node(out, node, flags, indent);
    +                break;
    +
    +                // Unknown
    +            default:
    +                assert(0);
    +                break;
    +            }
    +            
    +            // If indenting not disabled, add line break after node
    +            if (!(flags & print_no_indenting))
    +                *out = Ch('
    '), ++out;
    +
    +            // Return modified iterator
    +            return out;
    +        }        
    +
         }
         //! endcond
     
    

    八、推断解析是否能成功

    </pre><pre name="code" class="cpp">    try {
            doc.parse<0>((char*)tmpbuf);//会改变參数的内容,tmpbuf的生命周期必须到解析完
        } catch (rapidxml::parse_error &e) {
            err="parse xml error. ";
            err+=e.what();
    		delete []tmpbuf;
    		return s_stl_ruleinfo;
        }
    



  • 相关阅读:
    【Spring-MVC】
    【多线程】线程池关闭
    【DDD】基于事件驱动EDA -- 待完成
    【DDD】编码实战
    【Elastic Search】01- 原理
    【DDD】基于DDD的分层设计
    【DDD】Thoughtworks笔记(编码样例) -- 未完成
    【DDD】Thoughtworks笔记(目录划分、异常设计)
    平方和求余
    Factoring a Polynomial
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4040082.html
Copyright © 2020-2023  润新知