Question

I'm trying to walk a yaml-cpp (0.5.1) node of which I don't know anything before. I know that there's a YAML::Dump which uses an emitter and node events to do that, but I'm wondering if there's a way without using emitters.

I tried the following code but failed to find the needed methods to determine all needed cases:

void yaml_cpp_TestFunc_recursedown(YAML::Node& node)
{
  for(YAML::const_iterator it=node.begin();it!=node.end();++it)
  {
     auto dit = *it;
     try
     {
        if (dit.IsDefined())
        {
           try
           {
              std::cout << dit.as<std::string>() << std::endl;
           }
           catch (...) { }
           yaml_cpp_TestFunc_recursedown(dit);
        }
        else {}
     }
     catch (const YAML::InvalidNode& ex)
     {
        try
        {
           if (dit.second.IsDefined())
           {
              try
              {
                 std::cout << dit.second.as<std::string>() << std::endl;
              }
              catch (...) { }
              yaml_cpp_TestFunc_recursedown(dit);
           }
           else {}
        }
        catch (...) { }
     }
     catch (...) { }
  }
}
void yaml_cpp_Test()
{
  const std::string testfile=".\\appconf.yaml";

  {
     // generate a test yaml
     YAML::Node node;
     node["paths"].push_back("C:\\test\\");
     node["paths"].push_back("..\\");
     node["a"] = "123";
     node["b"]["c"] = "4567";

     YAML::Emitter emitter;
     emitter << node;

     std::ofstream fout(testfile);
     fout << emitter.c_str();
  }

  {
     // try to walk the test yaml
     YAML::Node config = YAML::LoadFile(testfile);
     yaml_cpp_TestFunc_recursedown(config);
  }
}
Was it helpful?

Solution

You can check Node::Type() and handle accordingly:

void WalkNode(YAML::Node node) {
  switch (node.Type()) {
    case YAML::NodeType::Null:
      HandleNull();
      break;
    case YAML::NodeType::Scalar:
      HandleScalar(node.Scalar());
      break;
    case YAML::NodeType::Sequence:
      for (auto it = node.begin(); it != node.end(); ++it) {
        WalkNode(*it);
      }
      break;
    case YAML::NodeType::Map:
      for (auto it = node.begin(); it != node.end(); ++it) {
        WalkNode(it->first);
        WalkNode(it->second);
      }
      break;
    case YAML::NodeType::Undefined:
      throw std::runtime_exception("undefined node!");
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top