1

这个问题主要针对 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 的建议是:

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

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

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

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

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

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

非常感谢您的想法!

4

1 回答 1

1

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

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

  1. YAML 和 JSON 之间存在区别:YAML 区分空节点和不存在的节点。

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

  3. 在 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。我很乐意这样做,所以如果您有任何想法,请告诉我。

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

于 2011-09-02T17:16:53.180 回答