Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I write a generic C++ function to parse xml into structs?

I have a collection of xml data files representing objects of interest in images (rectangles, points, labelled faces, etc.) that I want to parse to produce vectors of structs. The files are manually created (and so are not just the result of serialising some C++ objects) and are of the following form:

<root>
<image filename=whatever>
<object>
  <x>1</x>
  <y>2</y>
</object>
<object>
  <x>3</x>
  <y>4</y>
</object>
</image>
<image filename=something>
 ...
</image>
</root>

So a collection of images, each of which contains a collection of object children, each of which has children giving the data relevant to that object. The structure of this data varies between files, e.g. in one file each object might just have an x and a y and in another each object might contain ints x1, y1, x2, y2 and a double z.

I want to parse such a file to produce a vector of Objects, where Object is a struct, in this case of the form struct Object { int x; int y; }.

For different choices of Object, I've currently got separate functions that use rapidxml to parse the xml in identical ways, except for which fields they extract.

I'd like to write a templated function so that you can merely specify the elements of a struct in some way and have the function return a vector of the appropriate structs. i.e. The user should specify a list of pairs ("x1", int), ("x2", int), etc. and have the rest of the work be done automatically.

I'm sure there must be a nice boost solution to this problem that avoids having to use XML schema. How do I do this?

like image 947
theotherphil Avatar asked Jan 10 '13 11:01

theotherphil


People also ask

What is XML parser in C?

The Oracle XML parser for C reads an XML document and uses DOM or SAX APIs to provide programmatic access to its content and structure. You can use the parser in validating or nonvalidating mode. This chapter assumes that you are familiar with the following technologies: Document Object Model (DOM).

How do you parse an XML file?

To parse XML documents, use the XML PARSE statement, specifying the XML document that is to be parsed and the processing procedure for handling XML events that occur during parsing, as shown in the following code fragment.

How parse XML in C++?

XML Parser for C++ will check if an XML document is well-formed, and optionally validate it against a DTD. The parser will construct an object tree which can be accessed through a DOM interface or operate serially through a SAX interface.

Can browser parse XML?

All major browsers have a built-in XML parser to access and manipulate XML.


1 Answers

You could try Boost Property Tree.

It allows you to write your own load/save functions to map XML (or INI or JSON) data onto your own structures. See the tutorial.

It even uses RapidXML which you're already using.

Edit:

You could try something like

template<typename T>
struct Field
{
    typedef T type;
    std::string name;
};

template<typename... Fields>
std::tuple<typename Fields::type...>
load(const Data& data, Fields... f)
{
    return std::make_tuple( data.get<typename Fields::type>(f.name)... );
}

Where Data is some source of the input data, like a boost::ptree, and you'd use that function like this:

load(d, Field<int>{"x1"}, Field<int>{"x2"} );

Then you'd just need each data type to be constructible from a tuple of the right types.

like image 167
Jonathan Wakely Avatar answered Oct 06 '22 01:10

Jonathan Wakely