Because you specifically mentioned lightweight, and I haven't seen it mentioned, I'll add Boost.PropertyTree. It uses RapidXML under the hood.
It doesn't do anything but parse elements, but sometimes that is enough. And honestly, XML schema verification, XPath, and co. deserve to be split into separate libraries. It probably wouldn't be hard to tie in the existing C++ amalgamations that provide this extra coverage.
Example XML file/string:
std::string xml_providers =
"<question>"
" <title>What’s a good way to write XML in C++?</title>"
" <date>2010/6/6</date>"
"</question>"
"<providers>"
" <provider speed=\"1\">Boost.PropertyTree</provider>"
" <provider speed=\"6\">TinyXML++</provider>"
" <provider speed=\"3\">PugiXML</provider>"
" <provider speed=\"9001\">Xerxes</provider>"
" <provider speed=\"1\">RapidXML</provider>"
"</providers>";
boost::property_tree
would be used like so:
using boost::property_tree::xml_parser::read_xml;
using boost::property_tree::ptree;
using boost::gregorian::from_string;
using boost::gregorian::date;
ptree doc;
std::istringstream iss(xml_providers);
xml_parser::read_xml(iss, doc);
std::string title = doc.get<std::string>("question.title");
date when = from_string(doc.get<std::string>("question.date"));
ptree providers = doc.get_child("providers");
std::size_t size = std::distance(providers.begin(), providers.end());
std::cout << "Question: " << title << std::endl;
std::cout << "Asked on: " << when << std::endl;
std::cout << size << " suggested XML providers" << std::endl << std::endl;
std::cout << std::left << std::setw(25)
<< "Provider" << "Speed" << std::endl;
providers.sort(sort_by_speed);
std::for_each(providers.begin(), providers.end(), send_to_cout);
And the two helper functions:
auto sort_by_speed = [](ptree::value_type& a, ptree::value_type& b) -> bool {
int a_speed = a.second.get<int>("<xmlattr>.speed");
int b_speed = b.second.get<int>("<xmlattr>.speed");
return a_speed < b_speed;
};
auto send_to_cout = [](ptree::value_type& provider) {
std::cout << std::left << std::setw(25)
<< provider.second.get_value<std::string>()
<< provider.second.get<int>("<xmlattr>.speed") << std::endl;
};
Output:
Question: WhatÆs a good way to write XML in C++?
Asked on: 2010-Jun-06
5 suggested XML providers
Provider Speed
Boost.PropertyTree 1
RapidXML 1
PugiXML 3
TinyXML++ 6
Xerxes 9001
It's so easy that you don't even need to know XML!
(Ignore the speed ratings I attributed the libraries. I made them up.)
edit: property_tree supports exporting XML from a ptree object, of course. I wrote an example for reading XML because (1) it's the only usage I am familiar with, and (2) there are very few examples online.