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才能显示。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果需要源码可以发送邮件到sdiwen1982@sohu.com索取 /*************************************** 功能:读取xml文件 参数:[in] xml文件路径 返回:true读取成功 false读取失败 **************************************/ bool ReadXml(CString sXmlPath /*xml文件路径*/); /*************************************** 功能:写入xml文件 参数:[in] xml文件路径 返回:true写入成功 false写入失败 **************************************/ bool WriteXml(CString sXmlPath /*xml文件路径*/); /*************************************** 功能:释放空间 参数:无 返回:无 **************************************/ void Release(); /*************************************** 功能:删除指定的节点 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteNode(); /*************************************** 功能:删除当前节点的所有子节点,当前节点不删除 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteAllSon(); /*************************************** 功能:根据索引删除子节点 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteSonByIndex(unsigned int nIndex); /*************************************** 功能:删除节点所有属性 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteAllAttr(); /*************************************** 功能:根据属性名删除属性 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteAttrByName(CString sName); /*************************************** 功能:根据索引删除属性 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteAttrByIndex(unsigned int nIndex); /*************************************** 功能:根据属性名设置属性值 参数:[in] sName 属性名 [in] sValue 属性值 返回:true设置成功 false设置失败 **************************************/ bool SetAttrValueByName(CString sName, CString sValue); /*************************************** 功能:插入属性 参数:[in] sName 属性名 [in] sValue 属性值 返回:true插入成功 false插入失败 **************************************/ bool InsertAttr(CString sName, CString sValue); /*************************************** 功能:设置节点值 参数:[in] sValue 属性值 返回:true设置节点值成功 false设置节点值失败 **************************************/ bool SetNodeValue(CString sValue); /*************************************** 功能:插入子节点 参数:[in] sName 节点名 返回:非空表示插入节点成功,返回插入的新节点指针 空表示插入失败 **************************************/ CXMLNode * InsertNode(CString sName); /*************************************** 功能:判断是否存在子节点 参数:[in] pNode 子节点文件指针, 返回:false没有子节点 true有子节点 **************************************/ bool HasChild(MSXML2::IXMLDOMNodePtr pNode);

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值