The following describes the old API. For the new API, see the Tutorial.
Contents
Basic Parsing
The parser accepts streams, not file names, so you need to first load the file. Since a YAML file can contain many documents, you can grab them one-by-one. A simple way to parse a YAML file might be:
Note that dereferencing a map iterator is undefined; instead, use the first and second methods to get the key and value nodes, respectively.
Alternatively, we can pick off the values one-by-one, if we know the keys:
YAML::Node doc; // already parsed
std::string name;
doc["name"] >> name;
int age;
doc["age"] >> age;
std::cout << "Found entry with name '" << name << "' and age '" << age << "'\n";
One thing to be keep in mind: reading a map by key (as immediately above) requires looping through all entries until we find the right key, which is an O(n) operation. So if you're reading the entire map this way, it'll be O(n^2). For small n, this isn't a big deal, but I wouldn't recommend reading maps with a very large number of entries (>100, say) this way.
Optional Keys
If you try to access a key that doesn't exist, yaml-cpp throws an exception (see When Something Goes Wrong. If you have optional keys, it's often easier to use FindValue instead of operator[]:
The above three methods can be combined to read from an arbitrary document. But we can make life a lot easier. Suppose we're reading 3-vectors (i.e., vectors with three components), so we've got a structure looking like this:
struct Vec3 {
float x, y, z;
};
We can read this in one operation by overloading the extraction (>>) operator:
void operator >> (const YAML::Node& node, Vec3& v)
{
node[0] >> v.x;
node[1] >> v.y;
node[2] >> v.z;
}
// now it's a piece of cake to read it
YAML::Node doc; // already parsed
Vec3 v;
doc >> v;
std::cout << "Here's the vector: (" << v.x << ", " << v.y << ", " << v.z << ")\n";
A Complete Example
Here's a complete example of how to parse a complex YAML file:
... we throw an exception (all exceptions are derived from YAML::Exception). If there's a parsing exception (i.e., a malformed YAML document), we throw a YAML::ParserException:
If you make a programming error (say, trying to read a scalar from a sequence node, or grabbing a key that doesn't exist), we throw some kind of YAML::RepresentationException. To prevent this, you can check what kind of node something is:
The intent is that if you'd like to keep a YAML::Node around for longer than the document will stay in scope, you can clone it and store it as long as you like.
The old API breaks if you skip to this section without reading the earlier tutorial section "Converting To/From Native Data Types" wherein the righteous path creating template functions to encode() and decode() your non-native types (like Vec3).
You'll see complaints that operator >> is being implemented. And when you implement them you'll use functions like asstd::string(), as<float>(), etc.
Seeing how sweet as<T>() works, you'll want to implement your own and THEN you must take delivery from the clue train at "Converting To/From Native Data Types."