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

     

  • 相关阅读:
    Atitit.ati orm的设计and架构总结 适用于java c# php版
    Atitit.ati dwr的原理and设计 attilax 总结 java php 版本
    Atitit.ati dwr的原理and设计 attilax 总结 java php 版本
    Atitit. 软件设计 模式 变量 方法 命名最佳实践 vp820 attilax总结命名表大全
    Atitit. 软件设计 模式 变量 方法 命名最佳实践 vp820 attilax总结命名表大全
    Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结
    Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结
    atitit.基于  Commons CLI 的命令行原理与 开发
    atitit.基于  Commons CLI 的命令行原理与 开发
    atitit.js 与c# java交互html5化的原理与总结.doc
  • 原文地址:https://www.cnblogs.com/MenAngel/p/11552588.html
Copyright © 2011-2022 走看看