【问题标题】:How do I write a generic C++ function to parse xml into structs?如何编写通用 C++ 函数来将 xml 解析为结构?
【发布时间】:2013-01-10 11:17:12
【问题描述】:

我有一组 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。

我想解析这样一个文件以生成一个对象向量,其中 Object 是一个结构,在本例中为 struct Object { int x;整数y; }。

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

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

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

【问题讨论】:

  • 你试过用libxml++吗?
  • 我没有,但文档表明它只是一个基本的 XML 解析器,并不能解决我的问题。我错过了什么吗?
  • 由于 C++ 没有反射,如果没有大量模拟反射的代码,您基本上无法做您想做的事。最好弄清楚你需要的所有具体类型,然后使用代码生成来管理它。
  • 在不知道更多细节的情况下,我不能说更具体的东西,但您可以调整您的结构以适应 boost::fusion 列表 (boost.org/doc/libs/1_52_0/libs/fusion/doc/html/fusion/adapted/…),然后自动填充列表来自 XML 的数据。使用可变参数模板可能很难使用,因为您不知道数据的到来顺序..

标签: c++ xml templates boost


【解决方案1】:

你可以试试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"} );

那么你只需要每个数据类型都可以从正确类型的元组中构造出来。

【讨论】:

  • 这为 XML 解析提供了更好的界面,但似乎无法解决我的问题;对于每个数据对象的选择,您仍然需要一个单独的函数,不是吗?
  • 比写通用版本更容易、更快捷。
  • 我已经用一些可能有帮助的东西更新了答案,但你总是需要做的不仅仅是("x1", int), ("x2", int),因为你需要将它们映射到Object::x1Object::x2,这可以' 没有额外的输入就不能完成(即使它只是包括 &amp;Object::x1 以及 "x1"int)......除非你完全摆脱你的对象类型,只使用元组来保存数据
  • 谢谢,看来可以。可悲的是,我不能使用 C++11 功能。我想我可以用带有类型列表的东西替换可变参数模板。你是对的,一点代码重复会更容易和更快,但我对如何通用地完成这一点很感兴趣。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2018-11-27
    • 2016-05-02
    • 1970-01-01
    • 2015-08-01
    • 2010-12-23
    • 2019-02-17
    • 2018-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多