HCKRMVT
HCKRMVT

Reputation: 414

YAML parsing subsections using cpp

I have this config in a .yaml:

server:
    - address: "0:0"
    - address: "0:0"

virtual-hosts:
    - address: "0:0"
    - http:
        root: "/www/index.html"
        server-name: "lambda"
    - address:

protocol: http-1.0

modules:
    - ssl-2.7
    - cgi-php-1.0

I'm trying to extract each value from each key (from each node) but as I start using YAML::const_iterators or YAML::iterators to cycle through all of them, I'm prompted with this error: invalid node; this may result from using a map iterator as a sequence iterator, or vice-versa. I tried checking up the difference between map iterator an sequence iterator and I can't even manage to find helpful documentation.

Here's some code I've tried as a result of reading the YAML CPP references and looking up for solutions out here:

YAML::Node config = YAML::LoadFile(path);
YAML::Node vhosts_n = config["virtual-hosts"];

...

for(YAML::iterator param = vhosts_n.begin(); param != vhosts_n.end(); ++param) {
    std::string tmp = param->first.as<std::string>();
    std::cout << tmp << std::endl;
}
for(YAML::iterator param = vhosts_n.begin(); param != vhosts_n.end(); ++param) {
    std::string tmp = *param;
    std::cout << tmp->first.as<std::string>() << std::endl;
}
for(YAML::const_iterator param = vhosts_n.begin(); param != vhosts_n.end(); ++param)
    std::cout << param->first.as<std::string>() << std::endl;

Upvotes: 0

Views: 904

Answers (1)

Kafka
Kafka

Reputation: 810

I am not totally sure if it's not a bug, but you can use param->begin() as a step in your loop. An example :

#include "yaml-cpp/yaml.h"

#include <iostream>
#include <string>

int main()
{
  YAML::Node config = YAML::LoadFile("YOUR PATH");
  YAML::Node vhosts_n = config["virtual-hosts"];

  for(YAML::const_iterator param = vhosts_n.begin(); param != vhosts_n.end(); ++param)
    {
      switch (param->Type()) {
      case YAML::NodeType::Null:
        std::cout << "null" << std::endl;
        break;
      case YAML::NodeType::Scalar: 
        std::cout << "scalar" << std::endl;
          break;
      case YAML::NodeType::Sequence: 
        std::cout << "seq" << std::endl;
        break;
      case YAML::NodeType::Map: 
      {
        std::cout << "map" << std::endl;
        auto n = param->begin();
        std::string map_first = n->first.as<std::string>();
        std::string map_second = n->second.as<std::string>();
        std::cout << map_first << " " << map_second << std::endl;
        break;
      }
      case YAML::NodeType::Undefined:
        std::cout << "undef" << std::endl;
      }
    }
}

Note that code will crash because of :

    - http:
        root: "/www/index.html"
        server-name: "lambda"

You have to manage this case.

Upvotes: 2

Related Questions