• C++ xml 解析器


      C++的xml解析器有很多,这个知乎回答里有一个列表:https://www.zhihu.com/question/32046606

      下面使用其中的RapidXml试试。

      官方地址: https://link.zhihu.com/?target=http%3A//rapidxml.sourceforge.net/

      Manual地址:http://rapidxml.sourceforge.net/manual.html

      这里有个例子:https://www.cnblogs.com/lancidie/p/3304089.html

      上面代码是在ubuntun下是编译不过的,我作了小的更改:

      编译环境:Ubuntu 16.04   、 gcc version 5.4.0

      下载了上面rapidxml 1.13版本,这个版本在此环境下,仍需要打一个补丁,其实就是在rapidxml_print.hpp开头加了以下几行声明,放在类内部开始即可。

    1         template<class OutIt, class Ch> inline OutIt print_children(OutIt out, const xml_node<Ch> *node, int flags, int indent);
    2         template<class OutIt, class Ch> inline OutIt print_element_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
    3         template<class OutIt, class Ch> inline OutIt print_data_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
    4         template<class OutIt, class Ch> inline OutIt print_cdata_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
    5         template<class OutIt, class Ch> inline OutIt print_declaration_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
    6         template<class OutIt, class Ch> inline OutIt print_comment_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
    7         template<class OutIt, class Ch> inline OutIt print_doctype_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
    8         template<class OutIt, class Ch> inline OutIt print_pi_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
    View Code

      整个代码如下:

      1 #include "rapidxml/rapidxml.hpp"
      2 #include "rapidxml/rapidxml_print.hpp"
      3 #include "rapidxml/rapidxml_utils.hpp"
      4 
      5 #include <string>
      6 #include <iostream>
      7 #include <fstream>
      8 
      9 using namespace rapidxml;
     10 using namespace std;
     11 
     12 void WriteXml1()
     13 {
     14     xml_document<> doc;
     15     xml_node<>* rot = doc.allocate_node(rapidxml::node_pi,doc.allocate_string("xml version='1.0' encoding='utf-8'"));
     16     doc.append_node(rot);
     17     xml_node<>* node =   doc.allocate_node(node_element,"config",NULL);
     18     xml_node<>* color =   doc.allocate_node(node_element,"color",NULL);
     19     doc.append_node(node);
     20     node->append_node(color);
     21     color->append_node(doc.allocate_node(node_element,"red","0.1"));
     22     color->append_node(doc.allocate_node(node_element,"green","0.1"));
     23     color->append_node(doc.allocate_node(node_element,"blue","0.1"));
     24     color->append_node(doc.allocate_node(node_element,"alpha","1.0"));
     25 
     26     xml_node<>* size =   doc.allocate_node(node_element,"size",NULL);
     27     size->append_node(doc.allocate_node(node_element,"x","640"));
     28     size->append_node(doc.allocate_node(node_element,"y","480"));
     29     node->append_node(size);
     30 
     31     xml_node<>* mode = doc.allocate_node(rapidxml::node_element,"mode","screen mode");
     32     mode->append_attribute(doc.allocate_attribute("fullscreen","false"));
     33     node->append_node(mode);
     34 
     35     std::string text;
     36     rapidxml::print(std::back_inserter(text), doc, 0);
     37 
     38     std::cout<<text<<std::endl;
     39 
     40     std::ofstream out("config.xml");
     41     out << doc;
     42 }
     43 
     44 void WriteXml2()
     45 {
     46     xml_document<> doc; //是解析器
     47     char a[] = "<top>"//如果单独传, 就不能加上xml的头部信息,
     48             //否则会报错
     49             "<name>tangqiang</name>"
     50             "<age>22</age>"
     51             "</top>";
     52     char* p = a;
     53     doc.parse<0>(p);
     54 
     55     xml_node<>* node = doc.first_node();//去顶级结点
     56     cout << (node->name())<< endl;
     57     node = node->first_node();
     58     while (node) {
     59         cout << node->name() << node->value() << endl;//name() value()返回的字符串不会去掉首尾的空白字符
     60         node = node->next_sibling();
     61     }
     62 
     63     ofstream out("test.xml");//ofstream 默认时,如果文件存在则会覆盖原来的内容,不存在则会新建
     64     out << doc;//doc 这样输出时在目标文件中不会有xml 头信息---<?xml version='1.0' encoding='utf-8' >
     65     out.close();
     66 }
     67 
     68 void ReadXml()
     69 {
     70     file<> fdoc("config.xml");
     71     std::cout<<fdoc.data()<<std::endl;
     72     xml_document<>   doc;
     73     doc.parse<0>(fdoc.data());
     74 
     75     std::cout<<doc.name()<<std::endl;
     76 
     77     //! 获取根节点
     78     xml_node<>* root = doc.first_node();
     79     std::cout<<root->name()<<std::endl;
     80 
     81     //! 获取根节点第一个节点
     82     xml_node<>* node1 = root->first_node();
     83     std::cout<<node1->name()<<std::endl;
     84 
     85     xml_node<>* node11 = node1->first_node();
     86     std::cout<<node11->name()<<std::endl;
     87     std::cout<<node11->value()<<std::endl;
     88 
     89     //! 添加之后再次保存
     90     //需要说明的是rapidxml明显有一个bug
     91     //那就是append_node(doc.allocate_node(node_element,"h","0"));的时候并不考虑该对象是否存在!
     92     xml_node<>* size = root->first_node("size");
     93     size->append_node(doc.allocate_node(node_element,"w","0"));
     94     size->append_node(doc.allocate_node(node_element,"h","0"));
     95 
     96     std::string text;
     97     rapidxml::print(std::back_inserter(text),doc,0);
     98 
     99     std::cout<<text<<std::endl;
    100 
    101     std::ofstream out("config.xml");
    102     out << doc;
    103 }
    104 
    105 void DeleteXml()
    106 {
    107     file<> fdoc("config.xml");
    108     xml_document<> doc;
    109     doc.parse<0>(fdoc.data());
    110 
    111     std::string text;
    112     rapidxml::print(std::back_inserter(text), doc, 0);
    113     std::cout<<text<<std::endl;
    114 
    115     xml_node<>* root = doc.first_node();
    116 
    117     xml_node<>* sec = root->first_node();
    118 
    119     root->remove_node(sec); //移除根节点下的sec结点(包括该结点下所有结点)
    120     text="删除一个节点
    ";
    121     rapidxml::print(std::back_inserter(text), doc, 0);
    122     std::cout<<text<<std::endl;
    123 
    124     root->remove_all_nodes(); //移除根节点下所有结点
    125     text="删除所有节点
    ";
    126     rapidxml::print(std::back_inserter(text), doc, 0);
    127     std::cout<<text<<std::endl;
    128 
    129     std::ofstream out("test.xml");
    130     out<<doc;
    131 }
    132 
    133 void EditXml()
    134 {
    135     file<> fdoc("config.xml");
    136     std::cout<<fdoc.data()<<std::endl;
    137     xml_document<> doc;
    138     doc.parse<0>(fdoc.data());
    139 
    140     std::cout<<doc.name()<<std::endl;
    141 
    142     //! 获取根节点
    143     xml_node<>* root = doc.first_node();
    144     xml_node<>* delnode = root->first_node("color");
    145     root->remove_node(delnode);//先删除address节点
    146     //
    147     xml_node<>* lnode = root->first_node("size");//找到post节点
    148     xml_node<>* mynode=doc.allocate_node(node_element,"address","河北");
    149     root->insert_node(lnode,mynode);
    150 
    151     std::string text;
    152     rapidxml::print(std::back_inserter(text),doc,0);
    153 
    154 
    155     std::cout<<text<<std::endl;
    156 
    157     std::ofstream out("version.xml");
    158     out << doc;
    159 }
    160 
    161 void TravelsalXml()
    162 {
    163     file<> fdoc("config.xml");
    164     //std::cout<<fdoc.data()<<std::endl;
    165     xml_document<> doc;
    166     doc.parse<0>(fdoc.data());
    167 
    168     //std::cout<<doc.name()<<std::endl;
    169 
    170     //! 获取根节点
    171     xml_node<>* root = doc.first_node();
    172 
    173     for(rapidxml::xml_node<char> * node = root->first_node();
    174         node != NULL;
    175         node = node->next_sibling())
    176     {
    177         std::cout<<(node->name())<<"  "<<(node->value())<<endl;
    178     }
    179 
    180     std::cout<<"travesal from size node"<<std::endl;
    181     for(rapidxml::xml_node<char> * node = root->first_node("size");
    182         node != NULL;
    183         node = node->next_sibling())
    184     {
    185         std::cout<<(node->name())<<"  "<<(node->value())<<endl;
    186     }
    187 }
    188 
    189 void TravelsalAttrXml()
    190 {
    191     file<> fdoc("config.xml");
    192     xml_document<> doc;
    193     doc.parse<0>(fdoc.data());
    194 
    195     //! 获取根节点
    196     xml_node<>* root = doc.first_node();
    197     xml_node<>* subroot = root->first_node("mode");
    198 
    199     for(rapidxml::xml_attribute<char> * attr = subroot->first_attribute("fullscreen");
    200         attr != NULL;
    201         attr = attr->next_attribute())
    202     {
    203         //char * value = attr->value();
    204 
    205         cout<<(attr->name())<<" "<<(attr->value())<<endl;
    206     }
    207 }
    208 
    209 int main()
    210 {
    211     //WriteXml1();
    212     //WriteXml2();
    213     //ReadXml();
    214     //DeleteXml();
    215     //EditXml();
    216 
    217     //TravelsalXml();
    218     TravelsalAttrXml();
    219 
    220     return 0;
    221 }
    View Code

      总结:以上代码演示了写XML、读XML、删除某一个节点、遍历所有的节点、遍历所有的属性。

      RapidXml可以说,使用起来非常方便。

  • 相关阅读:
    iOS 自动续期订阅 恢复购买
    iOS内购恢复购买
    iOS内购自动续订
    iOS苹果内购服务端技术方案
    Spring4.x体系架构
    Linux下MySQL主从复制(Binlog)的部署过程
    Linux下MySQL多实例部署记录
    Linux下MySQL基础及操作语法
    Linux下Nginx基础应用
    Linux下Apache(HTTP)基础知识梳理-运维笔记
  • 原文地址:https://www.cnblogs.com/kanite/p/9182419.html
Copyright © 2020-2023  润新知