yaml-cpp 0.5 emiter yaml文件读取和写回

.环境

ubuntu16+qt5.6.2+yaml-cpp0.5.3

.前提

http://blog.csdn.net/azhuty/article/details/68485569yaml文件来源)

https://github.com/jbeder/yaml-cpp/wiki/How-To-Emit-YAML(更多细节可以参考他的wiki

环境都已经弄好了

.开工

在项目pro中添加yaml的静态库链接

LIBS    +=/home/Desktop/yaml-cpp-release-0.5.3/build/libyaml-cpp.a
INCLUDEPATH+= -l/home/Desktop/yaml-cpp-release-0.5.3/include/yaml-cpp -l

yaml文件格式

subscribers:  
  - name:        "Default task"  
    topic:       "input/cmd_default_check"  
    timeout:     0.5  
    priority:    1  
    short_desc:  "Default controller"  
  - name:        "Navigation stack"  
    topic:       "input/cmd_serial_navi"  
    timeout:     1.0  
    priority:    3  
    short_desc:  "Navigation controller"  
publisher:       "output/cmd_vel" 

然后qmake

头文件

#ifndef YAML_READ_WRITE_H
#define YAML_READ_WRITE_H
#include
#include

class yaml_read_write
{
public:
    yaml_read_write();
    YAML::Node DataMem;
    YAML::Emitter emitter;
    bool dump();
    bool setFilePath(std::string path);
private:
    std::string filename;
//    template 
//    T getValue(T);


};

#endif // YAML_READ_WRITE_H

DataMem:缓存的读取yaml数据

emitter用来写回文件的

filename具体的文件路径

yaml_cpp

#include "yaml_read_write.h"
#include
yaml_read_write::yaml_read_write()
{

}


bool yaml_read_write::dump()
{
    if(!filename.empty())
    {
        std::ofstream fout(filename);
        fout << emitter.c_str();
        return true;
    }
    return false;
}

bool yaml_read_write::setFilePath(std::string path)
{
    filename=path;
    if(!filename.empty())
    {
       DataMem=YAML::LoadFile(filename);
    }
    if (DataMem.IsNull())
            return false;
    return true;
}

读取部分

读取一个简单的数据

    ui->setupUi(this);
    yaml_read_write *yaml=new yaml_read_write();
   if( yaml->setFilePath("yaml.yml"))
   {
       YAML::Node Name=yaml->DataMem["subscribers"];
       std::string name=Name[0]["name"].as();
       ui->lineEdit->setText(QString::fromStdString(name));
} 
yaml-cpp 0.5 emiter yaml文件读取和写回_第1张图片

在这边需要注意你读取的结构一定要合理

DataMem相当于一个多维的数组你不能读取数组中不存在的项目会被异常


throw TypedBadConversion(node.Mark());

实际上name已经是key[subscribers]value


对于Map的读写

此时NameNode的内容如下Name是一个Map


yaml-cpp 0.5 emiter yaml文件读取和写回_第2张图片

对于list的读写

std::vectorv=Name[0]["list"].as>();(此时list里面都是int类型的数据其他也可以根据需要修改)

yaml-cpp 0.5 emiter yaml文件读取和写回_第3张图片

与需要上传的结果一致

yaml-cpp 0.5 emiter yaml文件读取和写回_第4张图片

写入文件部分

对原有数据进行修改


    yaml->DataMem["subscribers"][0]["list"][4]=55;
       yaml->DataMem["subscribers"][0]["list"][4]=11;   
       yaml->dump();
       


这边有一个好玩的地方

对列表进行修改的话,如果下标越界包括像这种yaml->DataMem["subscribers"][0]["list"]["Key"]="say"

会从sequenceturn to map


感觉大大棒棒哒(这一拨骚走位,服气)

yaml-cpp 0.5 emiter yaml文件读取和写回_第5张图片



改回来尝试另一种越狱


yaml-cpp 0.5 emiter yaml文件读取和写回_第6张图片

记住list现在长这样

 yaml->DataMem["subscribers"][0]["list"][5]=55;
 yaml->dump();
       

yaml->DataMem["subscribers"][0]["list"][5]=55;当超出list下标+1的时候也会自动变成map

追加新的内容

追加一个map

 yaml->emitter<DataMem;
 yaml->emitter<emitter<emitter<emitter<emitter<emitter<dump();
yaml-cpp 0.5 emiter yaml文件读取和写回_第7张图片

       std::vector  squares;
       squares.push_back(1);
       squares.push_back(4);
       squares.push_back(9);
       squares.push_back(16);

       std::map  ages;
       ages["Daniel"] = 26;
       ages["Jesse"] = 24;
       yaml->emitter << YAML::BeginSeq;
       yaml->emitter << YAML::Flow << squares;
       yaml->emitter << ages;
       yaml->emitter << YAML::EndSeq;

       yaml->dump();

yaml-cpp 0.5 emiter yaml文件读取和写回_第8张图片


在已有节点下追加内容

如何在subscribes节点下面插入格式一模一样的比较困难,目前只能找到一种替代方法

利用之前使用过的namenode(特别注意,这里面的Node都是浅复制,使用一片MEM对一个copy进行操作的话就会造成其他也改变)


       Name[2]["name"]="ll";
       Name[2]["ip"]="118";
yaml-cpp 0.5 emiter yaml文件读取和写回_第9张图片

总结

1.throwTypedBadConversion(node.Mark());这个异常一般都是对yaml结构没有理解清楚,不是其他错误,是缓存里面没有这个KEY

2.注意Node是浅复制,对它数据进行操作的时候需要小心,会影响到其他指向相同内存的Node节点,所以慎用新的Node节点来记录同一份DataMem






你可能感兴趣的:(yaml)