如何编写通用的C ++函数来将xml解析为结构体?

时间:2013-01-10 11:17:12

标签: c++ xml templates boost

我有一组xml数据文件,表示我想要解析的图像(矩形,点,标记的面等)中感兴趣的对象,以生成结构的向量。这些文件是手动创建的(因此不仅仅是序列化一些C ++对象的结果),并且具有以下形式:

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

所以一组图像,每个图像都包含一个对象子集合,每个对象子节点都有子节点,提供与该对象相关的数据。该数据的结构因文件而异,例如在一个文件中,每个对象可能只有一个x和一个y,而在另一个文件中,每个对象可能包含整数x1,y1,x2,y2和一个双z。

我想解析这样一个文件来生成一个Objects的向量,其中Object是一个struct,在这种情况下是struct Object {int x; int y; }。

对于Object的不同选择,我目前有单独的函数使用rapidxml以相同的方式解析xml,除了它们提取的字段。

我想编写一个模板化函数,这样你只需要以某种方式指定结构的元素,并让函数返回适当结构的向量。即用户应指定对的列表(“x1”,int),(“x2”,int)等,并自动完成其余工作。

我确信必须有一个很好的增强解决方案来解决这个问题,避免使用XML模式。我该怎么做呢?

2 个答案:

答案 0 :(得分:5)

您可以尝试Boost Property Tree

它允许您编写自己的加载/保存函数,以将XML(或INI或JSON)数据映射到您自己的结构上。请参阅tutorial

它甚至使用您已经使用的RapidXML。

修改

您可以尝试类似

的内容
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)... );
}

Data是输入数据的某些来源,例如boost::ptree,您可以像这样使用该函数:

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

然后你只需要从正确类型的元组构造每种数据类型。

答案 1 :(得分:0)

如果您可以为 XML 文件编写 XML 架构,则可以使用一些工具从架构生成 C++-API。关键字是“C++ XML 模式绑定”。

我使用过 XSD compiler 但还有其他类似的工具......