如何在yaml-cpp中合并节点 [英] How to merge node in yaml-cpp

查看:221
本文介绍了如何在yaml-cpp中合并节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个节点对象,像这样:

I have two node object, like this:

school:
  grade:
    class:
     name: bob
school:
  grade:
    class:
      age: 18

我要合并它,结果如下:

I want to merge it, the result like this:

school:
  grade:
    class:
      name: bob
      age: 18

如何合并?当节点大小和深度不知道时.

How to merge it? when the node size and depth do not kown.

推荐答案

这是我的尝试:

#include <yaml-cpp/yaml.h>

inline const YAML::Node & cnode(const YAML::Node &n) {
    return n;
}

YAML::Node merge_nodes(YAML::Node a, YAML::Node b)
{
  if (!b.IsMap()) {
    // If b is not a map, merge result is b, unless b is null
    return b.IsNull() ? a : b;
  }
  if (!a.IsMap()) {
    // If a is not a map, merge result is b
    return b;
  }
  if (!b.size()) {
    // If a is a map, and b is an empty map, return a
    return a;
  }
  // Create a new map 'c' with the same mappings as a, merged with b
  auto c = YAML::Node(YAML::NodeType::Map);
  for (auto n : a) {
    if (n.first.IsScalar()) {
      const std::string & key = n.first.Scalar();
      auto t = YAML::Node(cnode(b)[key]);
      if (t) {
        c[n.first] = merge_nodes(n.second, t);
        continue;
      }
    }
    c[n.first] = n.second;
  }
  // Add the mappings from 'b' not already in 'c'
  for (auto n : b) {
    if (!n.first.IsScalar() || !cnode(c)[n.first.Scalar()]) {
      c[n.first] = n.second;
    }
  }
  return c;
}

对于非标量键,我选择忽略节点等效性.请注意,此版本不会修改a.它返回一个新的映射c,该映射是ba的合并. b中的值将替换c映射中a中相同键控的非映射值.

For non-scalar keys I have opted to ignore node equivalence. Please note that this version does not modify a. It returns a new map c which is a merge of b into a. Values from b will replace identically keyed non-map values from a in the c map.

这篇关于如何在yaml-cpp中合并节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆