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

the*_*hil 5 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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

Jon*_*ely 5

你可以尝试Boost Property Tree.

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

它甚至使用您已经使用的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)... );
}
Run Code Online (Sandbox Code Playgroud)

Data输入数据的某些来源在哪里,比如a boost::ptree,你会使用这样的函数:

load(d, Field<int>{"x1"}, Field<int>{"x2"} );
Run Code Online (Sandbox Code Playgroud)

然后,您只需要从正确类型的元组构造每种数据类型.