1

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 far:

  • 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!

John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • 2
    Aside from the fact that you don't like that you have to set a macro to enable support for STL, what is wrong with TinyXML? – James McNellis Jun 06 '10 at 23:30
  • @James McNellis: The last time I tried the samples coming with the "C++" "wrapper" "ticpp" (I find that a little ironic, actually), The program just segfaulted. A quick analysis showed that the error came from TinyXML. So i stopped using it. –  Jun 06 '10 at 23:33
  • 1
    @nebukadnezzar: I've used TinyXML extensively and never had a problem with it. It's not perfect, but it's easy to use and fast enough for most purposes. – James McNellis Jun 06 '10 at 23:37
  • @James McNellis: Exactly, it's *far* from perfect. –  Jun 06 '10 at 23:53
  • 1
    @nebukadnezzar: If you're looking for a perfect library for anything, my only suggestion is to start writing it! – James McNellis Jun 06 '10 at 23:55
  • 1
    @James: ...and get used to dissapointment. – John Dibling Jun 07 '10 at 06:26

7 Answers7

2

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.

Community
  • 1
  • 1
Romain Hippeau
  • 24,113
  • 5
  • 60
  • 79
  • 1
    Though if "lightweight" was part of the requirements (which it seems to be from the other examples of libraries nebukadnezzar has already tried) then Xerces is on the totally other end of *that* scale! – Dean Harding Jun 07 '10 at 00:07
  • @cedeka: Yes, even though I haven't explicitly added as requirement, a lightweight library is what I'm looking for. –  Jun 07 '10 at 00:16
  • @codeka I think between the three options I mention this is covered. – Romain Hippeau Jun 07 '10 at 00:17
  • @nebukadnezzar the existing post to stackoverflow I mention also covers this. This is really a repeat question. – Romain Hippeau Jun 07 '10 at 00:18
  • @Romain Hippeau: I hate to admit it, but tinyxml++ seems to be the best solution here. –  Jun 07 '10 at 00:45
2

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...

Jon Watte
  • 6,579
  • 4
  • 53
  • 63
2

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.

Ephphatha
  • 586
  • 2
  • 8
2

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.

dean
  • 51
  • 1
  • 4
  • 8
  • I still feel a little bad for posting off topic. I was trying to show how ptree works as a DOM-like container. Given the example, how to use it for writing should become immediately apparent if you are familiar with the STL. – dean Jun 07 '10 at 16:27
  • -1 as it wasn't the question how to parse XML, but how to write XML. –  Jun 07 '10 at 20:13
  • Fair enough. But you have to realize property_tree is brand new. I doubt many are familiar with it. FWIW, you can add `write_xml("file.xml", doc)` at the end, and it will function exactly as XML+ostream. – dean Jun 07 '10 at 21:20
1

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.

Dean Harding
  • 71,468
  • 13
  • 145
  • 180
1

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

Buğra Gedik
  • 714
  • 8
  • 16
0

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.

Joshua
  • 40,822
  • 8
  • 72
  • 132