使用 yaml-cpp 更新 YAML 文档的节点和值

Updating node and values of YAML document with yaml-cpp

本文关键字:节点 文档 yaml-cpp 更新 YAML 使用      更新时间:2023-10-16

我需要解析C++中的一些 YAML(对 YAML 来说有点新(。我想使用 yaml-cpp。我的目标是:

  • 创建一些泛型/可重用实用工具函数来帮助分析此 YAML。
  • 为了能够更新 YAML::Node 和/或添加缺失值(通过指定默认值(

如果我举一些示例 YAML,它可能显示为:

...
comms:
messageBus:
remoteHost: "message-bus"
remotePort: 5672

甚至:

...
comms:

尽管如此,我希望能够更新反映默认值的 YAML。因此,要阅读上面的 YAML,代码如下所示:

auto &nodeComms = get_yaml_node_field_or_insert(node, "comms");
auto &nodeMessageBus = get_yaml_node_field_or_insert(nodeComms , "comms");
auto strRemoteHost = get_yaml_string_field_or_default_and_update(nodeMessageBus, "remoteHost", "127.0.0.1");
auto nRemotePort = get_yaml_uint16_field_or_default_and_update(nodeMessageBus, "remotePort", uint16_t{5672});

因此,如果在第二个示例上运行上述代码,则更新后的 YAML 现在将为:

...
comms:
messageBus:
remoteHost: "127.0.0.1"
remotePort: 5672

对于get_yaml_string_field_or_default_and_updateget_yaml_uint16_field_or_default_and_update,创建一个模板化函数来处理读取不同的值类型并在必要时插入它们是相当简单的:

///////////////////////////////////////////////////////////////////////////
template <typename TYPE_IN, typename TYPE_RETURN>
TYPE_RETURN get_type_from_yaml_node_or_default_and_update(YAML::Node &node,
const char *pchFieldName,
TYPE_IN nValueDefault) noexcept
{
if (!node)
{
assert(false);
throw std::runtime_error("Invalid node");
}
if (!node[pchFieldName])
{
node[pchFieldName] = nValueDefault;
return nValueDefault;
}
try
{
return node[pchFieldName].as<TYPE_RETURN>();
}
catch (const std::exception &e)
{
node[pchFieldName] = nValueDefault;
return nValueDefault;
}
catch (...)
{
node[pchFieldName] = nValueDefault;
return nValueDefault;
}
}

我正在努力的代码是get_yaml_node_field_or_insert

///////////////////////////////////////////////////////////////////////////
YAML::Node  &get_yaml_node_field_or_insert(YAML::Node &node, const char *pchFieldName) noexcept
{
if (!node)
{
assert(false);
throw std::runtime_error("Invalid node");
}
// TODO: Either 1) Return reference if it exists or 2) insert if it does not and return reference.
return node[pchFieldName];
}

看起来运算符 [] 没有根据 API 返回引用。

// indexing
template <typename Key>
const Node operator[](const Key& key) const;
template <typename Key>
Node operator[](const Key& key);

任何提示/建议将不胜感激。

YAML::Node 已经是一种引用类型,因此从函数返回它不会进行深度复制。它也是可变的,因此您只需对其进行编辑,更改将更新根节点。