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="删除一个节点\r\n"; 
 rapidxml::print(std::back_inserter(text), doc, 0); 
 std::cout<<text<<std::endl;

 root->remove_all_nodes(); //移除根节点下所有结点
 text="删除所有节点\r\n"; 
 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('\n'), ++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('\n'), ++out;
+
+            // Return modified iterator
+            return out;
+        }       
+
     }
     //! \endcond
 


Q:utf-8格式的xml读取时怎么才能不显示乱码
A:rapidxml不理会字符编码,你传给什么格式它就存什么格式。所以读取utf-8后需要转换为gbk才能显示。


关于raidxml资料相关的介绍网上有很多资料,在这里我就不重复介绍了,下面直接贴代码:

#include "stdafx.h"
#include "stdlib.h"
#include <iostream>

//下面三个文件是本段代码需要的库文件
#include "rapidxml/rapidxml.hpp"      
#include "rapidxml/rapidxml_utils.hpp"
#include "rapidxml/rapidxml_print.hpp"

int CreateXml();
int ReadAndChangeXml();
int _tmain(int argc, _TCHAR* argv[])
{
    //测试用例
    CreateXml();
    //测试用例
    ReadAndChangeXml();
    system("pause");
    return 0;
}
//创建一个名称为config2.xml文件
int CreateXml()
{
    rapidxml::xml_document<> doc;
    rapidxml::xml_node<>* rot = doc.allocate_node(rapidxml::node_pi,doc.allocate_string("xml version='1.0' encoding='utf-8'"));
    doc.append_node(rot);
    rapidxml::xml_node<>* node = doc.allocate_node(rapidxml::node_element,"config","information");
    doc.append_node(node);
    rapidxml::xml_node<>* color = doc.allocate_node(rapidxml::node_element,"color",NULL);
    node->append_node(color);
    color->append_node(doc.allocate_node(rapidxml::node_element,"red","0.1"));
    color->append_node(doc.allocate_node(rapidxml::node_element,"green","0.1"));
    color->append_node(doc.allocate_node(rapidxml::node_element,"blue","0.1"));
    color->append_node(doc.allocate_node(rapidxml::node_element,"alpha","1.0"));
    rapidxml::xml_node<>* size = doc.allocate_node(rapidxml::node_element,"size",NULL);
    size->append_node(doc.allocate_node(rapidxml::node_element,"x","640"));
    size->append_node(doc.allocate_node(rapidxml::node_element,"y","480"));
    node->append_node(size);
    rapidxml::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("config1.xml");
    out << doc;
 
    return 0;
}


//读取并修改config3.xml
int ReadAndChangeXml()
{
     rapidxml::file<> fdoc("config1.xml");
     std::cout<<fdoc.data()<<std::endl;
     rapidxml::xml_document<> doc;
     doc.parse<0>(fdoc.data());
     std::cout<<doc.name()<<std::endl;
     //! 获取根节点
     rapidxml::xml_node<>* root = doc.first_node();
    std::cout<<root->name()<<std::endl;
    //! 获取根节点第一个节点
    rapidxml::xml_node<>* node1 = root->first_node();
    std::cout<<node1->name()<<std::endl;
    rapidxml::xml_node<>* node11 = node1->first_node();
    std::cout<<node11->name()<<std::endl;
    std::cout<<node11->value()<<std::endl;
    //! 修改之后再次保存
    rapidxml::xml_node<>* size = root->first_node("size");
    size->append_node(doc.allocate_node(rapidxml::node_element,"w","1"));
    size->append_node(doc.allocate_node(rapidxml::node_element,"h","1"));
    std::string text;
    rapidxml::print(std::back_inserter(text),doc,0);
   std::cout<<text<<std::endl;
   std::ofstream out("config1.xml");
   out << doc;
  
   return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值