Можно ли пройтись по дереву yaml-cpp без использования событий эмиттера и узла?

Я пытаюсь пройти узел yaml-cpp (0.5.1), о котором раньше ничего не знал. Я знаю, что есть YAML::Dump, который использует эмиттер и события узла для этого, но мне интересно, есть ли способ без использования эмиттеров.

Я попробовал следующий код, но не смог найти необходимые методы для определения всех необходимых случаев:

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);
  }
}

person wonko realtime    schedule 22.01.2014    source источник


Ответы (1)


Вы можете проверить Node::Type() и обработать соответственно:

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!");
  }
}
person Jesse Beder    schedule 23.01.2014
comment
Здорово! Большое Вам спасибо. Я хотел бы добавить, что в некоторых случаях может быть удобно добавить текущий узел в качестве параметра для HandleNull(). - person wonko realtime; 24.01.2014