Yaml-cpp (new API) - nested map / sequence combina

2019-02-20 06:09发布

问题:

I'm having quite fundamental problems with this api's handling of maps vs sequences. Say I have the following structure:

foo_map["f1"] = "one";
foo_map["f2"] = "two";
bar_map["b1"] = "one";
bar_map["b2"] = "two";

I want this to be converted to the following YAML file:

Node: 
    - Foo:
      f1 : one
      f2 : two
    - Bar:
      b1 : one
      b2 : two

I would do so by doing:

node.push_back("Foo");
node["Foo"]["b1"] = "one";
...
node.push_back("Bar");

However at the last line node has now been converted from a sequence to a map and I get an exception. The only way I can do this is by outputting a map of maps:

Node:
    Foo:
      f1 : one
      f2 : two
    Bar:
      b1 : one
      b2 : two

The problem with this is if I cannot read back such files. If I iterate over Node, I'm unable to even get the type of the node iterator without getting an exception.

YAML::Node::const_iterator n_it = node.begin();

for (; n_it != config.end(); n_it++) {
        if (n_it->Type() == YAML::NodeType::Scalar) {
            // throws exception
        }
    }

This should be very simple to handle but has been driving me crazy!

回答1:

The YAML file

Node: 
    - Foo:
      f1 : one
      f2 : two
    - Bar:
      b1 : one
      b2 : two

is probably not what you expect. It is a map, with a single key/value pair; the key is Node and the value is a sequence; and each entry of that sequence is a map with three key/value pairs, and the value associated with, e.g., the Foo, is null. This last part is probably not what you expected. I'm guessing you wanted something more like what you actually got, i.e.:

Node:
    Foo:
      f1 : one
      f2 : two
    Bar:
      b1 : one
      b2 : two

The question now is how to parse this structure.

YAML::Node root = /* ... */;
YAML::Node node = root["Node"];

// We now have a map node, so let's iterate through:
for (auto it = node.begin(); it != node.end(); ++it) {
  YAML::Node key = it->first;
  YAML::Node value = it->second;
  if (key.Type() == YAML::NodeType::Scalar) {
    // This should be true; do something here with the scalar key.
  }
  if (value.Type() == YAML::NodeType::Map) {
    // This should be true; do something here with the map.
  }
}


标签: c++ yaml-cpp