如何使用 yaml-cpp 发出复杂的数据结构?

Posted

技术标签:

【中文标题】如何使用 yaml-cpp 发出复杂的数据结构?【英文标题】:How to use yaml-cpp to emit a complicated data structure? 【发布时间】:2011-09-02 16:33:19 【问题描述】:

此问题主要针对 yaml-cpp (Jesse Beder) 的作者,他要求在此处发布有关 yaml-cpp 使用的问题。

在许多位置,包括 yaml-cpp 文档, http://code.google.com/p/yaml-cpp/wiki/HowToEmitYAML#Using_Existing_Nodes

您提到 yaml-cpp 不提供修改内存中现有 YAML::Node 对象的方法,您对修改内存中 YAML 的建议是:

    使用我自己的数据结构将 YAML 存储在内存中,然后在序列化时以某种方式将其反馈给 yaml-cpp(本质上归结为在 YAML::Node 中重新实现多态性,并没有太大区别从重新实现大部分 yaml-cpp),或

    “目前最好的方法是使用发射器并从节点的子节点中挑选”,即文档中给出的示例。这种方法的问题在于它只适用于最简单的情况。假设我想向一系列地图添加一个元素,其中地图的一个元素本身就是一个列表?这会很快变得任意复杂!找到插入新数据的位置,发出操纵器,这一切都必须“手动”完成。

为了使问题更加复杂,Emitter 是一个格式化程序,它的唯一输出是一个字符串,所以我唯一的选择是发出带有我修改的整个 YAML 文档,然后重新将其重新解析为新的内存表示。如果我对文档进行大量更改,此操作的效率足迹会迅速增加。

我了解修改现有节点存在实施挑战(您如何处理对节点数据或子节点数据的现有引用?)。但是,在我看来,允许动态创建新的、独立的节点并将其插入内存树中至少应该是简单的。例如,JsonCpp 是如何实现的: http://jsoncpp.sourceforge.net

如果效率低下,这至少可以使您记录的“发射器”方法成为一种潜在可行的解决方法。

感谢您对这些问题的看法。不幸的是,这些限制非常严重,并且鉴于 yaml-cpp 是目前唯一的 C++/OO YAML 库,我想知道除了切换到 JSON 之外是否还有其他实用的替代方案。

非常感谢您的想法!

【问题讨论】:

【参考方案1】:

但是,在我看来,允许动态创建新的、独立的节点并将其插入内存树中至少应该很简单。

我很想做这个(并且我在这里查看了 JsonCpp),但是存在三个问题:

    YAML 和 JSON 有区别:YAML 区分空节点和不存在的节点。

    yaml-cpp当前的行为是在请求不存在的节点时抛出异常。

    在 YAML 中,映射可以有任意键。

对于问题 #2,这意味着我们可能必须(主要!)打破当前的行为,这让我犹豫不决。

例如在JsonCpp中,当你写

 root["encoding"];

如果它不存在,它将为您创建一个默认节点。在 yaml-cpp 中,如果不存在就会抛出异常。人们可能依赖如下代码:

try 
  root["encoding"]; // etc
catch(const YAML::Exception&) 
  // does not exist

最后,对于问题 #3,您将如何指定作为映射的键?如果有人写了

root[1] = 5;

root 实例化为具有空第一个元素的序列,还是具有单个键/值对1, 5 的映射?如果是后者(看起来更自然),那么

root[0] = 3;
root[1] = 5;

root[1] = 5;
root[0] = 3;

会有不同的行为,这是违反直觉的。

基本上,最重要的是我已经考虑过这个问题,但是我还没有为它想出一个足够好的 API。我很乐意这样做,所以如果您有任何想法,请告诉我。

也就是说,我不确定 *** 是否是进行此类讨论的最佳场所(我在 yaml-cpp 网站上写了这篇文章,因为很多人都在 wiki 上发布了操作方法问题) - 所以请随意给我发一封电子邮件(在我的用户页面上)。

【讨论】:

非常感谢您快速周到的回复,杰西。对此,我真的非常感激。我确实会发邮件给你跟进。

以上是关于如何使用 yaml-cpp 发出复杂的数据结构?的主要内容,如果未能解决你的问题,请参考以下文章

如何为特定的 yaml-cpp 节点设置发射样式

如何使用 yaml-cpp 发出带引号的字符串?

无法使用 yaml-cpp 发出空值

使用 YAML-CPP 发出解析文件

yaml-cpp 发出的结果字符串 (!<!>) 是啥?

通过 boost 属性树(递归)发出 YAML 迭代