The Lazy Programmer

June 7, 2010

An XML Writer for C++

Filed under: C++,XML — ferruccio @ 9:31 am
Tags: ,

I’ve worked on a couple of projects where XML files were generated via printfs or iostreams and this has always turned out to be a mistake. Maintaining such code can be tricky and you always spend an inordinate amount of time debugging the same type of problems over and over again. Usually a character with special meaning to XML (such as < or >) winds up not getting quoted correctly or you forget an end element tag.

The project I’m currently working on involves a search engine which returns its results in XML over an HTTP connection. I decided to use an XML writer rather than make the same mistake again. After looking around for an open source solution and not finding anything suitable for my needs, I decided to roll my own and place the project on Google Code.

To use xml-writer, simply drop xml_writer.h into your project directory and #include it as necessary. It is a very simple (less than 200 LOC) class. The accompanying unit tests also serve as documentation for its use.

Briefly, you instantiate an xml::writer object bound to an std::ostream. This allows you to send the resulting XML to a string (std::stringstream), a file (std::fostream) or any ostream compatible object. In my case, I created a stream object which writes directly to an HTTP connection.

You instantiate xml::element objects to actually create the XML element tags. An xml::element object has overloaded attr() methods to write element attributes and contents() to write element contents. When an xml::element object goes out of scope, it will write the necessary end element tag.

A simple example:

#include "xml_writer.h"
#include <sstream>
#include <iostream>

using namespace std;

int main()
{
    stringstream ss;
    xml::writer xw(ss);
    {
        xml::element record("record", xw);
        record.attr("name", "fred").attr("age", 35);
        record.contents("yabba dabba doo!");
    }
    cout << ss.str() << endl;
    return 0;
}

will result in the following output:

<?xml version=”1.0″ encoding=”utf-8″?><record name=”fred” age=”35″>yabba dabba doo!</record>

NB: the extra scope created to encapsulate the record element was necessary so that the xml::element destructor is called before the resulting string is output. xml::element should always be enclosed in some kind of local scope for this to work properly.

Blog at WordPress.com.