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:
```
#include <fstream>
#include "yaml-cpp/yaml.h"
int main()
{
std::ifstream fin("test.yaml");
YAML::Parser parser(fin);
YAML::Node doc;
while(parser.GetNextDocument(doc)) {
// ...
}
return 0;
}
```
# Reading From the Document #
Suppose we have a document consisting only of a scalar. We can read that scalar like this:
```
YAML::Node doc; // let's say we've already parsed this document
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<<"'andage'"<<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.
If you try to access a key that doesn't exist, `yaml-cpp` throws an exception (see [When Something Goes Wrong](https://github.com/jbeder/yaml-cpp/wiki/How-To-Parse-A-Document-(Old-API)#When_Something_Goes_Wrong). If you have optional keys, it's often easier to use `FindValue` instead of `operator[]`:
std::cout << "Key 'name' exists, with value '" <<name<<"'\n";
} else {
std::cout << "Key 'name' doesn't exist\n";
}
```
# Getting More Complicated #
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:
... 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`:
```
try {
std::ifstream fin("test.yaml");
YAML::Parser parser(fin);
YAML::Node doc;
parser.GetNextDocument(doc);
// do stuff
} catch(YAML::ParserException& e) {
std::cout <<e.what()<<"\n";
}
```
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:
```
YAML::Node node;
YAML::NodeType::value type = node.Type(); // should be:
// YAML::NodeType::Null
// YAML::NodeType::Scalar
// YAML::NodeType::Sequence
// YAML::NodeType::Map
```
# Note about copying `YAML::Node` #
Currently `YAML::Node` is non-copyable, so you need to do something like
```
const YAML::Node& node = doc["whatever"];
```
This is intended behavior. If you want to copy a node, use the `Clone` function:
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.