解析此表单的yaml文件时遇到一个非常简单的问题:
- Foo
- Bar:
b1: 5
我想将顶级键解析为字符串,即“Foo”和“Bar”。 如您所见,序列中的第一个条目是标量,第二个条目是包含一个键/值对的映射。假设我已将此YAML文本加载到名为config的节点中。我按以下方式迭代配置:
YAML::Node::const_iterator n_it = config.begin();
for (; n_it != config.end(); n_it++) {
std::string name;
if (n_it->Type() == YAML::NodeType::Scalar)
name = n_it->as<std::string>();
else if (n_it->Type() == YAML::NodeType::Map) {
name = n_it->first.as<std::string>();
}
}
问题在于解析第二个“Bar”条目。我得到以下yaml-cpp异常,告诉我我正在尝试从序列迭代器n_it访问密钥。
YAML::InvalidNode: yaml-cpp: error at line 0, column 0: invalid node; this may result from using a map iterator as a sequence iterator, or vice-versa
如果我更改了对此的访问权限:
name = n_it->as<std::string>();
我得到一个不同的yaml-cpp异常,我猜是因为我试图以std :: string
的形式访问整个地图YAML::TypedBadConversion<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >: yaml-cpp: error at line 0, column 0: bad conversion
有人可以向我解释出现了什么问题吗?
编辑:新问题 我仍然遇到这个api处理地图与序列的问题。现在说我有以下结构:
foo_map["f1"] = "one";
foo_map["f2"] = "two";
bar_map["b1"] = "one";
bar_map["b2"] = "two";
我希望将其转换为以下YAML文件:
Node:
- Foo:
f1 : one
f2 : two
- Bar:
b1 : one
b2 : two
我会这样做:
node.push_back("Foo");
node["Foo"]["b1"] = "one";
...
node.push_back("Bar");
然而,在最后一行节点现在已经从一个序列转换为一个映射,我得到一个例外。我能做到这一点的唯一方法是输出地图地图:
Node:
Foo:
f1 : one
f2 : two
Bar:
b1 : one
b2 : two
这个问题是我无法读回这些文件。如果我遍历Node,我甚至无法获得节点迭代器的类型而不会出现异常。
YAML::Node::const_iterator n_it = node.begin();
for (; n_it != config.end(); n_it++) {
if (n_it->Type() == YAML::NodeType::Scalar) {
// throws exception
}
}
这应该很容易处理,但一直让我发疯!
答案 0 :(得分:4)
在你的表达中
name = n_it->first.as<std::string>();
n_it
是一个序列迭代器(因为它是顶级节点的迭代器),你刚刚建立了指向地图的迭代器。也就是说,
YAML::Node n = *n_it;
是一个地图节点。此映射节点(在您的示例中)如下所示:
Bar:
b1: 5
换句话说,它有一个键/值对,键是一个字符串,值是一个映射节点。听起来你想要字符串键。所以:
assert(n.size() == 1); // Verify that there is, in fact, only one key/value pair
YAML::Node::const_iterator sub_it = n.begin(); // This iterator points to
// the single key/value pair
name = sub_it->first.as<std::string>();
答案 1 :(得分:0)
尝试这样的事情:
- Foo: {}
- Bar:
b1: 15
答案 2 :(得分:0)
Sample.yaml
config:
key1: "SCALER_VAL" # SCALER ITEM
key2: ["val1", "val2"] #SEQUENCE ITEM
key3: # MAP ITEM
nested_key1: "nested_val"
#SAMPLE CODE for Iterate Yaml Node;
YAML::Node internalconfig_yaml = YAML::LoadFile(configFileName);
const YAML::Node &node = internalconfig_yaml["config"];
for(const auto& it : node )
{
std::cout << "\nnested Key: " << it.first.as<std::string>() << "\n";
if (it.second.Type() == YAML::NodeType::Scalar)
{
std::cout << "\nnested value: " << std::to_string(it.second.as<int>()) << "\n";
}
if (it.second.Type() == YAML::NodeType::Sequence)
{
std::vector<std::string> temp_vect;
const YAML::Node &nestd_node2 = it.second;
for(const auto& it2 : nestd_node2)
{
if (*it2)
{
std::cout << "\nnested sequence value: " << it2.as<std::string>() << "\n";
temp_vect.push_back(it2.as<std::string>());
}
}
std::ostringstream oss;
std::copy(temp_vect.begin(), temp_vect.end(),
std::ostream_iterator<std::string>(oss, ","));
std::cout << "\nnested sequence as string: " <<oss.str() << "\n";
}
if (it2.second.Type() == YAML::NodeType::Map)
{
// Iterate Recursively again !!
}
}
请参阅here了解更多详情;