首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用yaml-cpp更新YAML文档的节点和值

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

Stack Overflow用户
提问于 2020-01-31 22:39:55
回答 1查看 758关注 0票数 1

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

  • 创建一些通用/可重用实用程序函数,以帮助解析此YAML。
  • 要能够更新YAML::节点和/或添加缺失值(通过指定默认值)

如果我以YAML为例,它可能看起来如下:

代码语言:javascript
运行
复制
...
  comms:
    messageBus:
      remoteHost: "message-bus"
      remotePort: 5672

甚至:

代码语言:javascript
运行
复制
...
  comms:

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

代码语言:javascript
运行
复制
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现在将是:

代码语言:javascript
运行
复制
...
  comms:
    messageBus:
      remoteHost: "127.0.0.1"
      remotePort: 5672

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

代码语言:javascript
运行
复制
///////////////////////////////////////////////////////////////////////////
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

代码语言:javascript
运行
复制
///////////////////////////////////////////////////////////////////////////
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];
}

看起来,operator[]似乎没有根据API返回引用。

代码语言:javascript
运行
复制
// indexing
template <typename Key>
const Node operator[](const Key& key) const;

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

如有任何建议或建议,将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-31 23:04:24

节点已经是一个引用类型了,所以从函数中返回它不会产生很深的副本。它也是可变的,所以您只需编辑它,更改就会更新根节点。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60012219

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档