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可以说,使用起来非常方便。

原文地址:https://www.cnblogs.com/kanite/p/9182419.html