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