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);
整个代码如下:
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 }
总结:以上代码演示了写XML、读XML、删除某一个节点、遍历所有的节点、遍历所有的属性。
RapidXml可以说,使用起来非常方便。