https://github.com/jbeder/yaml-cpp/wiki/Tutorial
典型的加载YAML文件的例子:
YAML::Node config = YAML::LoadFile("config.yaml"); //执行文件同级目录
if (config["lastLogin"]) //如果文件节点有成员节点lastLogin
{
//获取并打印文件节点的成员节点lastLogin,转化为数据结构DateTime
std::cout << "Last logged in: " << config["lastLogin"].as
}
const std::string username = config["username"].as
const std::string password = config["password"].as
config["lastLogin"] = getCurrentDateTime();
std::ofstream fout("config.yaml"); fout << config;
基本解析和节点编辑
在文件YAML里面所有信息以节点形式表示。可以检查节点的类型如:YAML::NodeType::Sequence/Null/Scalar/Map/Undefined
集合节点(Sequence组或map结构)与STL的vector和map结构用法一致
Sequence的用法如下
YAML::Node primes = YAML::Load("[2, 3, 5, 7, 11]");
for (std::size_t i=0;i
{
std::cout << primes[i].as
} // or:
for (YAML::const_iterator it=primes.begin();it!=primes.end();++it)
{ std::cout << it->as
primes.push_back(13);
assert(primes.size() == 6);
Map的用法如下:
YAML::Node lineup = YAML::Load("{1B: Prince Fielder, 2B: Rickie Weeks, LF: Ryan Braun}");
for(YAML::const_iterator it=lineup.begin();it!=lineup.end();++it)
{ std::cout << "Playing at " << it->first.as
lineup["RF"] = "Corey Hart";
lineup["C"] = "Jonathan Lucroy";
assert(lineup.size() == 5);
创建节点
YAML::Node node; // starts out as null新建一个空的节点
node["key"] = "value"; // it now is a map node 节点为MAP结构
node["seq"].push_back("first element"); // node["seq"] automatically becomes a sequence //节点为数组结构
node["seq"].push_back("second element");
node["mirror"] = node["seq"][0]; // this creates an alias//创建了一个引用
node["seq"][0] = "1st element"; // this also changes node["mirror"] node["mirror"] = "element #1"; // and this changes node["seq"][0] - they're really the "same" node
node["self"] = node; // you can even create self-aliases
node[node["mirror"]] = node["seq"]; // and strange loops :)
生成的节点为
&1 key: value
&2 seq: [&3 "element #1", second element]
mirror: *3
self: *1
*3 : *2
数组节点转换为map节点
YAML::Node node = YAML::Load("[1, 2, 3]");
node[1] = 5; // still a sequence, [1, 5, 3] 仍然是一个数组
node.push_back(-3) // still a sequence, [1, 5, 3, -3] 仍然是一个数组
node["key"] = "value"; // now it's a map! {0: 1, 1: 5, 2: 3, 3: -3, key: value} //转换为map节点
下面这个例子也可以转换为MAP
YAML::Node node = YAML::Load("[1, 2, 3]");
node[3] = 4; // still a sequence, [1, 2, 3, 4]
node[10] = 10; // now it's a map! {0: 1, 1: 2, 2: 3, 3: 4, 10: 10}
与本地数据结构互相转换
YAML::Node node = YAML::Load("{pi: 3.14159, [0, 1]: integers}");
// this needs the conversion from Node to double 转换为double类型
double pi = node["pi"].as
// this needs the conversion from double to Node
node["e"] = 2.71828;
// this needs the conversion from Node to std::vector
std::vector
v.push_back(0);
v.push_back(1);
std::string str = node[v].as
与自定义类型互相转换
自定义类型为:
struct Vec3 { double x, y, z; /* etc - make sure you have overloaded operator== */ };
特化模板类YAML::convert<>
namespace YAML {
template<>
struct convert
static Node encode(const Vec3& rhs) {
Node node;
node.push_back(rhs.x);
node.push_back(rhs.y);
node.push_back(rhs.z);
return node; }
static bool decode(const Node& node, Vec3& rhs)
{ if(!node.IsSequence() || node.size() != 3)
{ return false; }
rhs.x = node[0].as
rhs.y = node[1].as
rhs.z = node[2].as
return true; }
};
}
使用方法:
YAML::Node node = YAML::Load("start: [1, 3, 0]");
Vec3 v = node["start"].as
node["end"] = Vec3(2, -1, 0);
https://github.com/jbeder/yaml-cpp/wiki/How-To-Emit-YAML
基本发布
YAML::Emitter
相当于一个输出流
YAML::Emitter
,可以通过
c_str()
获取值。
#include "yaml-cpp/yaml.h"
int main()
{
YAML::Emitter out;
out << "Hello, World!";
std::cout << "Here's the output YAML:\n" << out.c_str(); // prints "Hello, World!"
return 0; }
简单的列表和Maps
YAML::Emitter out;
out << YAML::BeginSeq; //开始列表
out << "eggs";
out << "bread";
out << "milk";
out << YAML::EndSeq; //结束列表
生成:
- eggs
- bread
- milk
YAML::Emitter out;
out << YAML::BeginMap; //开始Map
out << YAML::Key << "name"; //键
out << YAML::Value << "Ryan Braun"; //值
out << YAML::Key << "position";
out << YAML::Value << "LF";
out << YAML::EndMap; //结束Map
生成:
name: Ryan Braun
position: LF
还可以嵌套:
YAML::Emitter out;
out << YAML::BeginMap;
out << YAML::Key << "name";
out << YAML::Value << "Barack Obama";
out << YAML::Key << "children";
out << YAML::Value << YAML::BeginSeq << "Sasha" << "Malia" << YAML::EndSeq;
out << YAML::EndMap;
生成:
name: Barack Obama
children:
- Sasha
- Malia
使用Manipulators控制输出格式
YAML::Emitter out;
out << YAML::Literal << "A\n B\n C";
输出
|
A
B
C
YAML::Emitter out;
out << YAML::Flow;
out << YAML::BeginSeq << 2 << 3 << 5 << 7 << 11 << YAML::EndSeq;
输出
[2, 3, 5, 7, 11]
注释:
YAML::Emitter out; o
ut << YAML::BeginMap;
out << YAML::Key << "method";
out << YAML::Value << "least squares";
out << YAML::Comment("should we change this method?");
out << YAML::EndMap;
输出
method: least squares # should we change this method?
aliases/anchors
YAML::Emitter out;
out << YAML::BeginSeq;
out << YAML::Anchor("fred");
out << YAML::BeginMap;
out << YAML::Key << "name" << YAML::Value << "Fred";
out << YAML::Key << "age" << YAML::Value << "42";
out << YAML::EndMap;
out << YAML::Alias("fred");
out << YAML::EndSeq;
输出
- &fred
name: Fred
age: 42
- *fred
已经给 std::vector, std::list, 和 std::map重载了符号 <<
std::vector
squares.push_back(1);
squares.push_back(4);
squares.push_back(9);
squares.push_back(16);
std::map
ages["Daniel"] = 26;
ages["Jesse"] = 24;
YAML::Emitter out;
out << YAML::BeginSeq;
out << YAML::Flow << squares;
out << ages;
Out << YAML::EndSeq;
输出
- [1, 4, 9, 16]
- Daniel: 26
Jesse: 24
可以为自定义类型重载符号<<
struct Vec3 { int x; int y; int z; };
YAML::Emitter& operator << (YAML::Emitter& out, const Vec3& v) {
out << YAML::Flow;
out << YAML::BeginSeq << v.x << v.y << v.z << YAML::EndSeq;
return out;
}