zoukankan      html  css  js  c++  java
  • (4)rapidxml的详解及使用

        RapidXml是指 XML DOM解析工具包,是一个快速的读写xml文件的库文件(hpp)。

        (1)创建XML文件

    #include <iostream>
    #include <string>
    #include <fstream>
    #include "string.h"
    #include "rapidxml.hpp"
    #include "rapidxml_print.hpp"
    #include "rapidxml_utils.hpp"
    
    static const int buf_len = 2048;
    static char buf[buf_len] = { 0 };
    
    void createXML(const char * file_name)
    {
      // 1.DOM
      rapidxml::xml_document<> doc;
    
      // 2.node_declaration
      rapidxml::xml_node<>* declaration = doc.allocate_node(rapidxml::node_declaration);
      declaration->append_attribute(doc.allocate_attribute("version", "1.0"));
      declaration->append_attribute(doc.allocate_attribute("encoding", "utf-8"));
      doc.append_node(declaration);
    
      // 3.node_pi
      rapidxml::xml_node<>* dec = doc.allocate_node(rapidxml::node_pi,doc.allocate_string("xml version="1.0" encoding="utf-8""));
      doc.append_node(dec);
    
      // 4.node_element
      rapidxml::xml_node<>* root = doc.allocate_node(rapidxml::node_element, "root");
      doc.append_node(root);
    
      // 5.node_comment
      rapidxml::xml_node<>* comment = doc.allocate_node(rapidxml::node_comment, 0, "这是一个注释节点");
      root->append_node(comment);
    
      rapidxml::xml_node<>* students = doc.allocate_node(rapidxml::node_element, "students");
    
      // 6.node_data
      rapidxml::xml_node<>* one_student = doc.allocate_node(rapidxml::node_element, "student");
      rapidxml::xml_node<>* name = doc.allocate_node(rapidxml::node_data,"node_name","11");
      one_student->append_node(name);
      students->append_node(one_student);
    
      // 7.node_element with value
      rapidxml::xml_node<>* two_student = doc.allocate_node(rapidxml::node_element, "student","22");
      students->append_node(two_student);
    
      // 8.set attribute
      rapidxml::xml_node<>* three_student = doc.allocate_node(rapidxml::node_element,"student","33");
      students->append_node(three_student);
      three_student->append_attribute(doc.allocate_attribute("course", doc.allocate_string(buf)));
      three_student->append_attribute(doc.allocate_attribute("score","98"));
    
      // 9.node_element without value
      rapidxml::xml_node<>* four_student = doc.allocate_node(rapidxml::node_element,"student");
      students->append_node(four_student);
    
      // 10.node_cdata
      rapidxml::xml_node<>* five_student = doc.allocate_node(rapidxml::node_cdata,"student","55");
      students->append_node(five_student);
    
      // 11.node_cdata
      rapidxml::xml_node<>* six_student = doc.allocate_node(rapidxml::node_pi,"student","66");
      students->append_node(six_student);
    
      // 12.node_cdata
      rapidxml::xml_node<>* seven_student = doc.allocate_node(rapidxml::node_doctype,"student","77");
      students->append_node(seven_student);
      root->append_node(students);
    
      // 13.输出DOM到命令行
      std::cout<<doc;
    
      // 14.输出DOM到文件
      std::ofstream outfile(file_name, std::ios::out);
      if (outfile)
      {
        char *end = rapidxml::print(buf, doc, 0);
        *end = 0;
        outfile << buf;
        outfile.close();
      }
    }
    
    int main()
    {
      const char *file_name = "rapid.xml";
      createXML(file_name);
      return 0;
    }
    <?xml version="1.0" encoding="utf-8"?>
    <?xml version="1.0" encoding="utf-8" ?>
    <root>
            <!--这是一个注释节点-->
            <students>
                    <student>11</student>
                    <student>22</student>
                    <student course="" score="98">33</student>
                    <student/>
                    <![CDATA[55]]>
                    <?student 66?>
                    <!DOCTYPE 77>
            </students>
    </root>

        (2)读取XML文件

    //rapidxml_utils.hpp
    file类
    data()  返回 char* 的xml文本内容
    size()  返回 unsigned int的文本数据长度
    定义:rapidxml::file<0> valName(“filepath”);
    //rapidxml.hpp
    xml_document类
    parse(Ch *text);将文本数据解析为DOM tree
    clear();清空DOM tree
    定义:rapidxml::xml_document<0> doc;
    const int parse_default = 0;
    const int parse_full = parse_declaration_node | parse_comment_nodes | parse_doctype_node | parse_pi_nodes | parse_validate_closing_tags
    #include <iostream>
    #include <string>
    #include <fstream>
    #include "unistd.h"
    #include "string.h"
    #include "rapidxml.hpp"
    #include "rapidxml_print.hpp"
    #include "rapidxml_utils.hpp"
    
    static const int buf_len = 2048;
    static char buf[buf_len] = { 0 };
    
    //利用rapidxml::file读取配置文件
    void readXMLByFile(const char *file_name)
    {
        try
        {
          // 1.清空缓冲区
          memset(buf,0,buf_len);
          // 2.拼接绝对路径
          std::string strXml = "/home/sunjimeng/test/";
          strXml.append(file_name);
          // 3.用file文件读入缓冲区
          rapidxml::file<> fdoc(strXml.c_str());
          // 4.打印从文件中读取的内容
          std::cout<<fdoc.data();
          // 5.解析获取DOM实例
          rapidxml::xml_document<> doc;
          doc.parse<0>(fdoc.data());
        }catch(rapidxml::parse_error e)
        {
          std::cout<<e.what()<<std::endl;
          return;
        }
    }
    void readXMLByStream(const char *file_name)
    {
      try
      {
        // 1.清空缓冲区
        memset(buf,0,buf_len);
        // 2.判断文件是否存在
        if(access(file_name,F_OK) == -1)
            std::cout<<"xml file "<<file_name<<"is not exits!"<<std::endl;
        // 3.实例化文件读取流
        std::ifstream infile(file_name, std::ios::in);
        if(!infile)
        {
            std::cout<<"file stream instance error!"<<std::endl;
            return;
        }
        // 4.读取文件内容到缓冲区
        infile.read(buf, buf_len);
        // 5.输出文件内容
        std::cout<<buf<<std::endl;
        // 6.实例化DOM
        rapidxml::xml_document<> doc;
        doc.parse<0>(buf);
      }catch(rapidxml::parse_error e)
      {
        std::cout<<e.what()<<std::endl;
        return;      
      }
    }
    int main()
    {
      const char *file_name = "rapid.xml";
      readXMLByFile(file_name);
      readXMLByStream(file_name);
      return 0;
    }

        (3)修改及删除(接着上文)

    //rapidxml.hpp
    xml_node类
    1)node_type type() const; 获取结点类型 获取的类型是枚举的
    2)Ch* name() const; 获取结点名
    3)std::size_t name_size() const; 获取结点名长度
    4)Ch* value() const; 获取结点值
    5)std::size_t value_size() const; 获取结点值长度
    6)xml_node* first_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const; 获取DOM Tree第一个子结点的指针
    第一个参数为节点名,如果给定第一个参数为”a”,则该函数寻找结点名为a的第一个子结点;第二个参数为结点名长度
    7)xml_node* last_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const; 获取DOM Tree最后一个子结点的指针
    参数含义同上
    8)xml_attribute* first_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const; 获取结点的第一个属性指针
    9)xml_attribute* next_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const; 获取结点的下一个属性指针
    10)xml_attribute* last_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;获取结点的最后一个属性指针
    11)xml_node* previous_sibling(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;获取上一个同级结点的指针
    12)xml_node* next_sibling(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const; 获取下一个同级结点的指针
    13)xml_attribute* first_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const; 获取第一个同级结点的指针
    14)xml_attribute* last_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const; 获取最后一个同级结点的指针
    15)void insert_node(xml_node< Ch > *where, xml_node< Ch > *child);在第一个参数指向的结点之前,插入一个结点
    xml_attribute类
    1)xml_attribute *previous_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const;获取前一个属性
    2)xml_attribute *next_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const;获取后一个属性
    #include <iostream>
    #include <string>
    #include <fstream>
    #include "unistd.h"
    #include "string.h"
    #include "rapidxml.hpp"
    #include "rapidxml_print.hpp"
    #include "rapidxml_utils.hpp"
    
    static const int buf_len = 2048;
    static char buf[buf_len] = { 0 };
    
    void parseXML(const char * file_name)
    {
      memset(buf,0,buf_len);
      try
      {
        std::ifstream infile(file_name, std::ios::in);
        if (!infile)
        {
          return;
        }
        infile.read(buf, buf_len);
        std::cout << buf << std::endl;
    
        rapidxml::xml_document<> doc;
        doc.parse<0>(buf);
        // 取得根节点
        rapidxml::xml_node<> *root = doc.first_node("root");
        // 遍历students的子节点
        int flag = 0;
        for (rapidxml::xml_node<> * node = root->first_node("students")->first_node(); node; node = node->next_sibling())
        {
          if(node->first_node() != NULL)
            std::cout<<"name :"<<node->name()<<" value : "<<node->value()<<std::endl;
          else
            std::cout<<"name :"<<node->name()<<" has no value!"<<std::endl;
          for(rapidxml::xml_attribute<> * attribute = node->first_attribute(); attribute; attribute = attribute->next_attribute())
            std::cout<<"      attribute name = "<<attribute->name()<<" attribute value = "<<attribute->value()<<std::endl;
        }
      } catch(rapidxml::parse_error e)
      {
        std::cout<<e.what()<<std::endl;
      }
    }
    void modifyXML(const char * file_name)
    {
      memset(buf,0,buf_len);
      //用file解析DOM时必须是绝对路径
      std::string strXml = "/home/sunjimeng/test/";
      strXml.append(file_name);
      rapidxml::file<> fdoc(strXml.c_str());
      //打印读取的文件
      //std::cout<<fdoc.data();
      rapidxml::xml_document<> doc;
      doc.parse<0>(fdoc.data());
      //取得根节点
      rapidxml::xml_node<> *root = doc.first_node("root");
      rapidxml::xml_node<> *students = root->first_node("students");
      if(students != NULL)
        std::cout<<"student is not null"<<std::endl;
      else
        return;
      //删除最后一个元素
      if(students->last_node() != NULL)
        students->remove_last_node();
      //删除第一个元素
      if(students->first_node() != NULL)
        students->remove_first_node();
      rapidxml::xml_node<> *ptrNode = students->first_node();
    
      int size = 0;
      while(ptrNode)
      {
        size++;
        //删除所有属性
        ptrNode->remove_all_attributes();
        ptrNode = ptrNode->next_sibling();
      }
      std::cout<<"size = "<<size<<std::endl;
      std::string text;
      rapidxml::print(std::back_inserter(text),doc,0);
      std::cout<<text<<std::endl;
      std::ofstream out(file_name);
      out<<doc;
    }
    int main()
    {
      const char *file_name = "rapid.xml";
      modifyXML(file_name);
      parseXML(file_name);
      return 0;
    }
    student is not null
    size = 1
    <root>
            <students>
                    <student>33</student>
            </students>
    </root>
    
    
    <root>
            <students>
                    <student>33</student>
            </students>
    </root>
    
    
    name :student value : 33

     

  • 相关阅读:
    【转】Yii的url美化管理
    【转】通过文件锁实现,程序开始运行时,先判断文件是否存在,若存在则表明该程序已经在运行了,如果不存在就用open函数创建该文件,程序退出时关闭文件并删除文件
    【转】关于C execlp函数的理解
    【转】shell循环,判断介绍,以及实例
    【转】Yii framework config 可以被配置的项目
    高级着色语言HLSL入门(7)
    c++中的string用法
    关于链表的创建 代码
    c++笔试题汇总
    TCP Socket编程 C/C++实现 (Windows Platform SDK)
  • 原文地址:https://www.cnblogs.com/MenAngel/p/11552588.html
Copyright © 2011-2022 走看看