Я люблю хранить технологическую конфигурацию моих программ и утилит в XML-файле.
Пока я делал приложения с использованием Qt использовал небольшой класс, который читал эту конфигурацию и сохранял её в QStringMap.
Однако возникла потребность сделать простую утилиту на C++ но без Qt, XML-парсером которой я пользовался.
Типичный формат моего XML таков:
<?xml version="1.0" encoding="utf-8"?> <registry> <version>1</version> <section id="common" > <parameter id="locale" >ru_RU.utf8</parameter> <parameter id="parameter1" >value1</parameter> <parameter id="parameter2" >value2</parameter> </section> </registry>Для чтения я без проблем воспользовался бесплатной библиотекой RapidXML 1.13. Сейчас она входит в Boost, но я попробовал также использовать её и отдельно (при сборке с помощью GNU C++/MinGW под Windows). Собственно библиотека эта состоит из трёх шабонных HPP-файлов, которые не требуют компиляции.
//#include <rapidxml.hpp> //using namespace rapidxml; #include <boost/property_tree/detail/rapidxml.hpp> using namespace boost::property_tree::detail::rapidxml; // ................. // --- xml_document<char> doc; //cout << "Parse..." << endl; try { ifstream file( fname_xml.c_str() ); vector<char> buffer((istreambuf_iterator<char>(file)), istreambuf_iterator<char>()); buffer.push_back('\0'); doc.parse<0>( &buffer[0] ); } catch (parse_error e) { cerr << "Fail. Parse error " << e.what() << endl; return 0; } xml_node<> *root_node = doc.first_node(); //cout << "Root found?" << endl; if (root_node!=NULL) { //cout << "Root found!" << root_node->name() << ":" << root_node->value() << endl; xml_node<> *node = root_node->first_node("section"); //if (node!=NULL) cout << "section found" << endl; if (node) node = node->first_node("parameter"); //if (node!=NULL) cout << "first parameter found" << endl; while (node!=NULL) { xml_attribute<>* a = node->first_attribute("id"); if (a!=NULL) { config[ a->value() ] = node->value(); } node = node->next_sibling(); } } cout << "========" << endl << "Check loaded configuration:" << endl; typedef map<string,string>::const_iterator it; for (it i=config.begin(); i!=config.end(); i++) { cout << i->first << "\t= " << i->second << endl; } cout << "Configuration loaded" << endl; // ---