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?
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).
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.
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.
All major browsers have a built-in XML parser to access and manipulate XML.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With