RapidXml使用方法

一、写xml 文件

[cpp]  view plain copy
  1. #include <iostream>  
  2. #include "rapidxml/rapidxml.hpp"  
  3. #include "rapidxml/rapidxml_utils.hpp"  
  4. #include "rapidxml/rapidxml_print.hpp"  
  5.   
  6. using namespace rapidxml;  
  7.   
  8. int main()  
  9. {      
  10.     xml_document<> doc;    
  11.     xml_node<>* rot = doc.allocate_node(rapidxml::node_pi,doc.allocate_string("xml version='1.0' encoding='utf-8'"));  
  12.     doc.append_node(rot);  
  13.     xml_node<>* node =   doc.allocate_node(node_element,"config","information");    
  14.     xml_node<>* color =   doc.allocate_node(node_element,"color",NULL);    
  15.     doc.append_node(node);  
  16.     node->append_node(color);  
  17.     color->append_node(doc.allocate_node(node_element,"red","0.1"));  
  18.     color->append_node(doc.allocate_node(node_element,"green","0.1"));  
  19.     color->append_node(doc.allocate_node(node_element,"blue","0.1"));  
  20.     color->append_node(doc.allocate_node(node_element,"alpha","1.0"));  
  21.   
  22.     xml_node<>* size =   doc.allocate_node(node_element,"size",NULL);   
  23.     size->append_node(doc.allocate_node(node_element,"x","640"));  
  24.     size->append_node(doc.allocate_node(node_element,"y","480"));  
  25.     node->append_node(size);  
  26.   
  27.     xml_node<>* mode = doc.allocate_node(rapidxml::node_element,"mode","screen mode");  
  28.     mode->append_attribute(doc.allocate_attribute("fullscreen","false"));  
  29.     node->append_node(mode);  
  30.   
  31.     std::string text;    
  32.     rapidxml::print(std::back_inserter(text), doc, 0);    
  33.   
  34.     std::cout<<text<<std::endl;   
  35.   
  36.     std::ofstream out("config.xml");  
  37.     out << doc;  
  38.   
  39.     system("PAUSE");  
  40.     return EXIT_SUCCESS;  
  41. }  


生成的xml如下

[html]  view plain copy
  1.   <?xml version="1.0" encoding="utf-8" ?>   
  2. <config>  
  3. <color>  
  4.   <red>0.1</red>   
  5.   <green>0.1</green>   
  6.   <blue>0.1</blue>   
  7.   <alpha>1.0</alpha>   
  8.   </color>  
  9. <size>  
  10.   <x>640</x>   
  11.   <y>480</y>   
  12.   </size>  
  13.   <mode fullscreen="false">screen mode</mode>   
  14.   </config>  

这里需要注意的是:rapidxml为了追求性能,减少内存拷贝,就尽可能的通过指针(内存地址)来访问用户的变量;这就对用户提出了要求:必须保证变量的生存周期,如果变量被销毁了,rapidxml就会访问无效的内存地址,引发不可控的后果。

可见下例:

rapidxml::xml_document<> doc;

void addNode(std::string value)
{
   rapidxml::xml_node<>* root = doc.allocate_node(rapidxml::node_element, "unregister_context");
   doc.append_node(root);

   root->append_node(doc.allocate_node(rapidxml::node_element, "who_register", value.c_str()));
}

这样插入是有问题的,value是临时变量,函数执行完之后就被释放了,正确的方法如下:

rapidxml::xml_document<> doc;

void addNode(std::string value)
{
   rapidxml::xml_node<>* root = doc.allocate_node(rapidxml::node_element, "unregister_context");
   doc.append_node(root);

   root->append_node(doc.allocate_node(rapidxml::node_element, "who_register", doc.allocate_string(value.c_str())));
}

待插入的值"变量value"是作为参数传递进来的,是临时变量。rapidxml为了追求极致性能,在append_node()函数中是直接通过指针来访问value变量的,并没有进行内存拷贝--因此rapidxml在这里提出了一个隐晦的前提条件:在xml对象doc的生命周期内,必须保证"变量value"能够被正常访问。


写文件例子2:

[cpp]  view plain copy
  1. #include <string>  
  2. #include <iostream>  
  3. #include <fstream>  
  4. #include "rapidxml/rapidxml.hpp"  
  5. #include "rapidxml/rapidxml_utils.hpp"  
  6. #include "rapidxml/rapidxml_print.hpp"  
  7.   
  8.   
  9. using namespace rapidxml;  
  10. using namespace std;  
  11.   
  12. int main(int argc, char* argv[])  
  13. {  
  14.   
  15.     xml_document<> doc; //是解析器  
  16.     char a[] = "<top>"//如果单独传, 就不能加上xml的头部信息,  
  17.                //否则会报错  
  18.                "<name>tangqiang</name>"  
  19.                "<age>22</age>"  
  20.                "</top>";  
  21.     char* p = a;  
  22.     doc.parse<0>(p);  
  23.   
  24.     xml_node<>* node = doc.first_node();//去顶级结点  
  25.     cout << (node->name())<< endl;  
  26.     node = node->first_node();  
  27.     while (node) {  
  28.         cout << node->name() << node->value() << endl;//name() value()返回的字符串不会去掉首尾的空白字符  
  29.         node = node->next_sibling();  
  30.     }  
  31.   
  32.     ofstream out("test.xml");//ofstream 默认时,如果文件存在则会覆盖原来的内容,不存在则会新建  
  33.     out << doc;//doc 这样输出时在目标文件中不会有xml 头信息---<?xml version='1.0' encoding='utf-8' >  
  34.     out.close();  
  35.     system("pause");  
  36.     return 0;  
  37. }  

生成的xml如下

[html]  view plain copy
  1. <top>  
  2.     <name>tangqiang</name>  
  3.     <age>22</age>  
  4. </top>  


二、读取xml文件

[cpp]  view plain copy
  1. #include <iostream>  
  2. #include "rapidxml/rapidxml.hpp"  
  3. #include "rapidxml/rapidxml_utils.hpp"  
  4. #include "rapidxml/rapidxml_print.hpp"  
  5.   
  6. using namespace rapidxml;  
  7.   
  8. int main()  
  9. {  
  10.     file<> fdoc("config.xml");  
  11.     std::cout<<fdoc.data()<<std::endl;  
  12.     xml_document<>   doc;  
  13.     doc.parse<0>(fdoc.data());  
  14.   
  15.     std::cout<<doc.name()<<std::endl;  
  16.   
  17.     //! 获取根节点  
  18.     xml_node<>* root = doc.first_node();  
  19.     std::cout<<root->name()<<std::endl;  
  20.   
  21.     //! 获取根节点第一个节点  
  22.     xml_node<>* node1 = root->first_node();  
  23.     std::cout<<node1->name()<<std::endl;  
  24.   
  25.     xml_node<>* node11 = node1->first_node();  
  26.     std::cout<<node11->name()<<std::endl;  
  27.     std::cout<<node11->value()<<std::endl;  
  28.   
  29.     //! 添加之后再次保存  
  30.     //需要说明的是rapidxml明显有一个bug  
  31. //那就是append_node(doc.allocate_node(node_element,"h","0"));的时候并不考虑该对象是否存在!  
  32.     xml_node<>* size = root->first_node("size");  
  33.     size->append_node(doc.allocate_node(node_element,"w","0"));  
  34.     size->append_node(doc.allocate_node(node_element,"h","0"));  
  35.   
  36.     std::string text;  
  37.     rapidxml::print(std::back_inserter(text),doc,0);  
  38.   
  39.     std::cout<<text<<std::endl;  
  40.   
  41.     std::ofstream out("config.xml");  
  42.     out << doc;  
  43.   
  44.     system("PAUSE");  
  45.     return EXIT_SUCCESS;  
  46. }  

生成的xml为

[html]  view plain copy
  1. <config>  
  2.     <color>  
  3.         <red>0.1</red>  
  4.         <green>0.1</green>  
  5.         <blue>0.1</blue>  
  6.         <alpha>1.0</alpha>  
  7.     </color>  
  8.     <size>  
  9.         <x>640</x>  
  10.         <y>480</y>  
  11.         <w>0</w>  
  12.         <h>0</h>  
  13.     </size>  
  14.     <mode fullscreen="false">screen mode</mode>  
  15. </config>  


三、删除节点

[cpp]  view plain copy
  1. #include "rapidxml/rapidxml.hpp"  
  2. #include "rapidxml/rapidxml_utils.hpp"  
  3. #include "rapidxml/rapidxml_print.hpp"  
  4.   
  5. #include<iostream>  
  6. using namespace rapidxml;  
  7.   
  8. int main()  
  9. {  
  10.     file<> fdoc("config.xml");  
  11.     xml_document<> doc;  
  12.     doc.parse<0>(fdoc.data());  
  13.   
  14.     std::string text;    
  15.     rapidxml::print(std::back_inserter(text), doc, 0);    
  16.     std::cout<<text<<std::endl;   
  17.   
  18.     xml_node<>* root = doc.first_node();  
  19.   
  20.     xml_node<>* sec = root->first_node();  
  21.   
  22.     root->remove_node(sec); //移除根节点下的sec结点(包括该结点下所有结点)  
  23.     text="删除一个节点\r\n";    
  24.     rapidxml::print(std::back_inserter(text), doc, 0);    
  25.     std::cout<<text<<std::endl;   
  26.   
  27.     root->remove_all_nodes(); //移除根节点下所有结点  
  28.     text="删除所有节点\r\n";    
  29.     rapidxml::print(std::back_inserter(text), doc, 0);    
  30.     std::cout<<text<<std::endl;   
  31.   
  32.     std::ofstream out("test.xml");  
  33.     out<<doc;  
  34.     system("pause");  
  35.     return 0;  
  36. }  

输出信息如下:

[html]  view plain copy
  1. <config>  
  2.     <color>  
  3.         <red>0.1</red>  
  4.         <green>0.1</green>  
  5.         <blue>0.1</blue>  
  6.         <alpha>1.0</alpha>  
  7.     </color>  
  8.     <size>  
  9.         <x>640</x>  
  10.         <y>480</y>  
  11.         <w>0</w>  
  12.         <h>0</h>  
  13.     </size>  
  14.     <mode fullscreen="false">screen mode</mode>  
  15. </config>  
  16.   
  17.   
  18. 删除一个节点  
  19.   
  20. <config>  
  21.     <size>  
  22.         <x>640</x>  
  23.         <y>480</y>  
  24.         <w>0</w>  
  25.         <h>0</h>  
  26.     </size>  
  27.     <mode fullscreen="false">screen mode</mode>  
  28. </config>  
  29.   
  30.   
  31. 删除所有节点  
  32.   
  33. <config/>  


四、编辑节点信息

暂时找到的编辑方法就是先删除再增加

[cpp]  view plain copy
  1. #include "rapidxml/rapidxml.hpp"  
  2. #include "rapidxml/rapidxml_utils.hpp"  
  3. #include "rapidxml/rapidxml_print.hpp"  
  4.   
  5. #include<iostream>  
  6. using namespace rapidxml;  
  7.   
  8. int main()  
  9. {  
  10.     file<> fdoc("config.xml");  
  11.     std::cout<<fdoc.data()<<std::endl;  
  12.     xml_document<> doc;  
  13.     doc.parse<0>(fdoc.data());  
  14.   
  15.     std::cout<<doc.name()<<std::endl;  
  16.   
  17.     //! 获取根节点  
  18.     xml_node<>* root = doc.first_node();  
  19.     xml_node<>* delnode = root->first_node("color");  
  20.     root->remove_node(delnode);//先删除address节点  
  21.     //  
  22.     xml_node<>* lnode = root->first_node("size");//找到post节点  
  23.     xml_node<>* mynode=doc.allocate_node(node_element,"address","河北");  
  24.     root->insert_node(lnode,mynode);  
  25.   
  26.     std::string text;  
  27.     rapidxml::print(std::back_inserter(text),doc,0);  
  28.   
  29.   
  30.     std::cout<<text<<std::endl;  
  31.   
  32.     std::ofstream out("version.xml");  
  33.     out << doc;  
  34.     system("pause");  
  35.     return 0;     
  36. }  

输出如下:

[html]  view plain copy
  1. <config>  
  2.   
  3.     <color>  
  4.   
  5.         <red>0.1</red>  
  6.   
  7.         <green>0.1</green>  
  8.   
  9.         <blue>0.1</blue>  
  10.   
  11.         <alpha>1.0</alpha>  
  12.   
  13.     </color>  
  14.   
  15.     <size>  
  16.   
  17.         <x>640</x>  
  18.   
  19.         <y>480</y>  
  20.   
  21.         <w>0</w>  
  22.   
  23.         <h>0</h>  
  24.   
  25.     </size>  
  26.   
  27.     <mode fullscreen="false">screen mode</mode>  
  28.   
  29. </config>  
  30.   
  31.   
  32.   
  33.   
  34.   
  35. <config>  
  36.     <address>河北</address>  
  37.     <size>  
  38.         <x>640</x>  
  39.         <y>480</y>  
  40.         <w>0</w>  
  41.         <h>0</h>  
  42.     </size>  
  43.     <mode fullscreen="false">screen mode</mode>  
  44. </config>  

五、遍历所有节点

[cpp]  view plain copy
  1. for(rapidxml::xml_node<char> * node = parent_node->first_node("node name");  
  2.     node != NULL;  
  3.     node = node->next_sibling())  
  4. {  
  5.     ...  
  6. }  

六、遍历所有属性

[cpp]  view plain copy
  1. for(rapidxml::xml_attribute<char> * attr = node->first_attribute("node name");  
  2.     attr != NULL;  
  3.     attr = attr->next_attribute())  
  4. {  
  5.     char * value = attr->value();  
  6. }  


七、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文件如下。

[plain]  view plain copy
  1. Index: rapidxml_print.hpp  
  2. ===================================================================  
  3. --- rapidxml_print.hpp  (revision 2025)  
  4. +++ rapidxml_print.hpp  (revision 2080)  
  5. @@ -101,68 +101,9 @@  
  6.    
  7.          ///  
  8.          // Internal printing operations  
  9. -      
  10. -        // Print node  
  11. +          
  12.          template<class OutIt, class Ch>  
  13. -        inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)  
  14. -        {  
  15. -            // Print proper node type  
  16. -            switch (node->type())  
  17. -            {  
  18. -  
  19. -            // Document  
  20. -            case node_document:  
  21. -                out = print_children(out, node, flags, indent);  
  22. -                break;  
  23. -  
  24. -            // Element  
  25. -            case node_element:  
  26. -                out = print_element_node(out, node, flags, indent);  
  27. -                break;  
  28. -              
  29. -            // Data  
  30. -            case node_data:  
  31. -                out = print_data_node(out, node, flags, indent);  
  32. -                break;  
  33. -              
  34. -            // CDATA  
  35. -            case node_cdata:  
  36. -                out = print_cdata_node(out, node, flags, indent);  
  37. -                break;  
  38. -  
  39. -            // Declaration  
  40. -            case node_declaration:  
  41. -                out = print_declaration_node(out, node, flags, indent);  
  42. -                break;  
  43. -  
  44. -            // Comment  
  45. -            case node_comment:  
  46. -                out = print_comment_node(out, node, flags, indent);  
  47. -                break;  
  48. -              
  49. -            // Doctype  
  50. -            case node_doctype:  
  51. -                out = print_doctype_node(out, node, flags, indent);  
  52. -                break;  
  53. -  
  54. -            // Pi  
  55. -            case node_pi:  
  56. -                out = print_pi_node(out, node, flags, indent);  
  57. -                break;  
  58. -  
  59. -                // Unknown  
  60. -            default:  
  61. -                assert(0);  
  62. -                break;  
  63. -            }  
  64. -              
  65. -            // If indenting not disabled, add line break after node  
  66. -            if (!(flags & print_no_indenting))  
  67. -                *out = Ch('\n'), ++out;  
  68. -  
  69. -            // Return modified iterator  
  70. -            return out;  
  71. -        }  
  72. +        inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);          
  73.            
  74.          // Print children of the node                                 
  75.          template<class OutIt, class Ch>  
  76. @@ -372,7 +313,69 @@  
  77.              *out = Ch('>'), ++out;  
  78.              return out;  
  79.          }  
  80. +          
  81. +        // Print node  
  82. +        template<class OutIt, class Ch>  
  83. +        inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)  
  84. +        {  
  85. +            // Print proper node type  
  86. +            switch (node->type())  
  87. +            {  
  88.    
  89. +            // Document  
  90. +            case node_document:  
  91. +                out = print_children(out, node, flags, indent);  
  92. +                break;  
  93. +  
  94. +            // Element  
  95. +            case node_element:  
  96. +                out = print_element_node(out, node, flags, indent);  
  97. +                break;  
  98. +              
  99. +            // Data  
  100. +            case node_data:  
  101. +                out = print_data_node(out, node, flags, indent);  
  102. +                break;  
  103. +              
  104. +            // CDATA  
  105. +            case node_cdata:  
  106. +                out = print_cdata_node(out, node, flags, indent);  
  107. +                break;  
  108. +  
  109. +            // Declaration  
  110. +            case node_declaration:  
  111. +                out = print_declaration_node(out, node, flags, indent);  
  112. +                break;  
  113. +  
  114. +            // Comment  
  115. +            case node_comment:  
  116. +                out = print_comment_node(out, node, flags, indent);  
  117. +                break;  
  118. +              
  119. +            // Doctype  
  120. +            case node_doctype:  
  121. +                out = print_doctype_node(out, node, flags, indent);  
  122. +                break;  
  123. +  
  124. +            // Pi  
  125. +            case node_pi:  
  126. +                out = print_pi_node(out, node, flags, indent);  
  127. +                break;  
  128. +  
  129. +                // Unknown  
  130. +            default:  
  131. +                assert(0);  
  132. +                break;  
  133. +            }  
  134. +              
  135. +            // If indenting not disabled, add line break after node  
  136. +            if (!(flags & print_no_indenting))  
  137. +                *out = Ch('\n'), ++out;  
  138. +  
  139. +            // Return modified iterator  
  140. +            return out;  
  141. +        }          
  142. +  
  143.      }  
  144.      //! \endcond  
  145.    


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值