开发者

What's a good way to write XML in C++?

There are plenty of Libraries to parse XML, but it seems there aren't many good (?) ways to write XML in C++.

Libraries I've been using so f开发者_JAVA百科ar:

  • PugiXML: really lightweight, very straightforwarded API, but it seems to lack a way to write XML (Or I haven't found it yet)
  • RapidXML: I don't have much experience with RapidXML; But it does look nice.
  • TinyXML: I find it odd that the STL TinyXML needs to be explicitly "enabled" in TinyXML - I mean, if your compiler doesn't support the STL, get a better one!

Anyway, to make my point clear, I have written a PHP Script that does what I plan to do in C++: http://codepad.org/RyhQSgcm

I really appreciate any help!


Xerces DOM Parser

Xerces-C++ is a validating XML parser written in a portable subset of C++. Xerces-C++ makes it easy to give your application the ability to read and write XML data. A shared library is provided for parsing, generating, manipulating, and validating XML documents using the DOM, SAX, and SAX2 APIs. For an introduction to programming with Xerces-C++ refer to the Programming Guide.

The POCO project also has an XMLWriter that will allow you to generate XML.

Of course there is always this existing StackOverflow post.


I use std::ostream::operator() and a simple function that will quote a string if necessary. Taking time and memory to build a DOM when all you want to do is exhale existing data into XML seems to be taking the long way around...


If you're working in C++ you should consider ticpp again. It doesn't take much to get set up and outputs (simple) valid xml using the exact syntax you'd expect from anything that deals with streams.

This link shows how to use the library, and the included build notes are sufficient to get everything set up.


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.


It was already mentioned in the comments, but I'm going to mention TinyXML again. I've never had any problems with it in the ~7 years I've been using it.

The API is not really idiomatic C++ (I've never really bothered with the "ticpp" wrapper myself) but it works well, it's fast and it's easy enough to wrap it yourself if your really don't like the API.


I would suggest CodeSynthesis xsd compiler and C++ tree mapping.


Most people are going to hate this answer, but I'm in the habit of writing XML longhand (in C++ this would be using ostream) and using third party libraries for reading XML.

I have not yet had the case to read and modify XML.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜