2012-02-09 3 views
0

Я начинаю использовать YAML и библиотеку yaml-cpp, чтобы проиндексировать мой файл. Я распространил пример «монстров» с некоторой информацией из моего собственного проекта. Код и файл yaml приведены ниже, но вот мой вопрос:Советы по проектированию структур данных для взаимодействия с yaml-cpp?

Нужно ли размещать все данные, которые я получаю из проекта в одну массивную структуру? В примере монстров чтение значений из документа doc [i] было простым, потому что это был список монстров. В моем примере у меня будет несколько списков, но также скаляры и т. Д. Единственный способ, которым я нашел это сделать, - составить список, который технически имеет только одну запись (т. Е. Есть один «-» наверху файла, и все отступы в блок). Я думаю, что ответ заключается в том, чтобы взять часть содержимого «проблемной» версии перегруженного >> оператора, но я не мог заставить его работать правильно, не имея этого содержимого внутри этой функции. Любая помощь или совет приветствуются.

ea_test.cpp:

#include "yaml-cpp/yaml.h" 
    #include <iostream> 
    #include <fstream> 
    #include <string> 
    #include <vector> 

    struct Vec2{ 
    double x, y; 
    }; 

    struct DecVar{ 
    std::string name; 
    std::string tag; 
     Vec2 range; 
    std::string description; 
    }; 

    struct ProblemFormulation{ 
    std::vector <DecVar> decvars; 
    int numrealizations; 
    }; 

    void operator >> (const YAML::Node& node, Vec2& v) { 
    node[0] >> v.x; 
    node[1] >> v.y; 
    } 

    void operator >> (const YAML::Node& node, DecVar& decvar){ 
    node["name"] >> decvar.name; 
    node["tag"] >> decvar.tag; 
     node["range"] >> decvar.range; 
    node["description"] >> decvar.description; 
    } 

    void operator >> (const YAML::Node& node, ProblemFormulation& problemformulation){ 
     node["realizations"] >> problemformulation.numrealizations; 
     std::cout << " read realizations!" << std::endl; 
     const YAML::Node& decvarNode = node["decisions"]; 
     for (unsigned int i = 0; i < decvarNode.size(); i++) 
     { 
    DecVar decvar; 
    decvarNode[i] >> decvar; 
     problemformulation.decvars.push_back(decvar); 
     } 
    } 

    int main() 
    { 
     std::ifstream fin("./ea.yaml"); 
     YAML::Parser parser(fin); 
     YAML::Node doc; 
     parser.GetNextDocument(doc); 
     std::cout << "entering loop" << std::endl; 

     ProblemFormulation problemformulation; 

     for (unsigned int i = 0; i < doc.size(); i++) 
     { 
       doc[i] >> problemformulation; 
     } 
     return 0; 
    } 

И ea.yaml:

- 
     realizations: 10 
     decisions: 
     - name: reservoir 
      tag: res_tag 
      range: [0, 1.0] 
      description: > 
      This is a description. 
     - name: flow 
      tag: flow_tag 
      range: [0, 2.0] 
      description: > 
      This is how much flow is in the system. 

Заранее спасибо за помощь и советы!

Редактировать: Я, вероятно, буду работать только с одним документом yaml, и есть только один объект проблемы, который когда-либо будет создан. Мой код адаптирует то, что вы сделали бы для списка, но только делает это один раз. Я хотел бы знать правильный способ «просто сделать это один раз», так как я думаю, что это было бы чище и сделать более красивым YAML-файл (без всяких вещей, отступающих на один блок без причины).

ответ

1

Когда вы пишете

for (unsigned int i = 0; i < doc.size(); i++) 
{ 
    doc[i] >> problemformulation; 
} 

это перебирает все записи в [предполагается, чтобы быть последовательность] документ и читает каждый из них. Если ваш узел верхнего уровня не является узлом последовательности, а вместо этого является «проблемой формулировки», то просто напишите

doc >> problemformulation; 
+0

Спасибо за помощь. У меня, вероятно, будет больше вопросов, но они будут писать их как полные, отдельные сообщения позже. – Joe