使用boost ptree将std :: list序列化为json [英] Serializing std::list into json with boost ptree

查看:325
本文介绍了使用boost ptree将std :: list序列化为json的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,所以我在最近几天碰到我的头,但我仍然无法得到它的权利。我有一个std :: list容器,我想将其序列化为JSON字符串,使我可以通过网络发送它。



注意:使用以下代码编译代码:

  g ++ -std = c ++ 11  - 主main.cpp DBAccess11.cpp -lsqlite3 -lboost_serialization 

我帮助了这是



以下是我的 DBAccess1.h 文件。

  #ifndef DBAccess1_HH 
# define DBAccess1_HH

#include< list> //我为了可读性删除了一些头
#include< boost / serialization / list.hpp>
#include< boost / property_tree / ptree.hpp>
#include< boost / property_tree / json_parser.hpp>

using namespace std;
使用boost :: property_tree :: ptree;
using boost :: property_tree :: read_json;
using boost :: property_tree :: write_json;
using boost :: property_tree :: basic_ptree;

// ============================== //
struct SiteCode
{
int siteID;
int siteCode;
};

inline ostream&运算符<< (ostream& out,SiteCode& site)
{
out< (<< site.siteID<<,<< site.siteCode<<);
return out;
}
// ============================== //

class sqliteDB {
list< SiteCode> Site_Code_list;
public:
list< SiteCode> GET_ALL_Site_Code();
void printList();
};
#endif **

下面是 DBAccess11.cpp 文件,其中定义了所有函数

  #include< list& //我为了可读性删除了一些头
#include< boost / property_tree / ptree.hpp>
#include< boost / property_tree / json_parser.hpp>
#include< boost / serialization / list.hpp>
#includeDBAccess1.h

使用boost :: property_tree :: ptree;
using boost :: property_tree :: read_json;
using boost :: property_tree :: write_json;
using boost :: property_tree :: basic_ptree;

list< SiteCode> sqliteDB :: GET_ALL_Site_Code()
{
sqlite3 * db;
const char * sql;
sqlite3_stmt * stmt;

int rc = sqlite3_open(/ path / to / database.db,& db);
sql =SELECT * FROM SiteCode;;
rc = sqlite3_prepare_v2(db,sql,-1,& stmt,0);

while(sqlite3_step(stmt)== SQLITE_ROW){

int A = sqlite3_column_int(stmt,0);
int B = sqlite3_column_int(stmt,1);

SiteCode信息;
info.siteID = A;
info.siteCode = B;

cout<<准备将数据推入列表<< endl;
Site_Code_list.push_back(info);
cout<<已成功推送数据<< endl;

ptree pt;
for(auto& entry:list< SiteCode> Site_Code_list)//< ERROR LINE80
pt.put(entry.siteID,entry.siteCode);
std :: ostringstream buf;
write_json(buf,pt,false);
cout<< buf.str()<< endl;
}

sqlite3_finalize(stmt);
sqlite3_close(db);
return Site_Code_list;
}
// =================================== ============= //
void sqliteDB :: printList()
{
int s = Site_Code_list.size();
cout<< List的大小是:< s<< endl;
for(list< SiteCode> :: iterator it = Site_Code_list.begin(); it!= Site_Code_list.end(); it ++)
cout< * it< ;
}

以下是 main.cpp

  #include< list> //我为了可读性删除了一些头
#include< boost / serialization / list.hpp>
#include< boost / property_tree / ptree.hpp>
#include< boost / property_tree / json_parser.hpp>

using namespace std;
using boost :: property_tree :: ptree;
using boost :: property_tree :: read_json;
using boost :: property_tree :: write_json;
using boost :: property_tree :: basic_ptree;

int main()
{
sqliteDB object1;
object1.GET_ALL_Site_Code();
object1.printList();
cout<< \\\
\\\
All语句已正确执行\\\
\\\
;
return 0;
}

我得到的错误如下:

  DBAccess11.cpp:在成员函数'std :: list< SiteCode> sqliteDB :: GET_ALL_Site_Code()':
DBAccess11.cpp:80:38:错误:Site_Code_list之前的主表达式
(auto& entry:list< SiteCode> Site_Code_list)
^
DBAccess11.cpp:80:38:error:expected')'before'Site_Code_list'
DBAccess11.cpp:80:52:error:expected';'before')token
for(auto& entry:list< SiteCode> Site_Code_list)
^

/ p>

(1)这是否是使用boost将 std :: list转换成JSON 的正确方法?如果否,那么应该如何做呢?
(注意 - 我只能使用boost而没有其他库)



(2)如果我的方法是正确的,

解决方案

树中的路径总是字符串。编译器会在消息的其余部分告诉你这一点。可以证明文档是一个更易读的来源:


两个 key_type data_type 是可配置的,但通常为 std :: string 此处




b
$ b


self_type& put(const path_type& path,const Type& value,Translator tr);


因此修复的本质是

  pt.put(std :: to_string(entry.id),entry.code ); 

我有一些侧面跟踪清理代码,所以这里:



自包含示例

  header 
#include< ostream>

struct SiteCode {
int id;
int code;

SiteCode(int id,int code):id(id),code(code)
{}

friend inline std :: ostream& <(std :: ostream& out,SiteCode const& site){
return out< (<< site.id<<,<< site.code<<);
}
};

#include< list> //我为了可读性删除了一些头

// FILE:sqliteDB头
类sqliteDB {
使用Records = std :: list< SiteCode> ;;
记录_records;

public:
void load();
记录const& get()const {return _records; }
void printList()const;
void writeJson(std :: ostream& os)const;
};

// FILE:一些sqlpp.hpp实用程序头(仅限内联实现)
#include< memory>
#include< sqlite3.h>

命名空间sqlpp {
使用database = std :: shared_ptr< :: sqlite3> ;;

void perror(int rc){
if(rc!= SQLITE_OK)throw std :: runtime_error(:: sqlite3_errstr(rc));
}

struct语句{
静态语句prepare(database db,std :: string const& sql){
:: sqlite3_stmt * stmt = nullptr;
perror(:: sqlite3_prepare_v2(db.get(),sql.c_str(),-1,& stmt,0));

return {handle(stmt,:: sqlite3_finalize),db};
}

int step(){return :: sqlite3_step(_stmt.get()); }
int column_int(int c){return :: sqlite3_column_int(_stmt.get(),c); }
private:
using handle = std :: shared_ptr< :: sqlite3_stmt>
database _db; // keep it around for the lifetime of _stmt
handle _stmt;

语句(handle& h,database& db):_db(db),_stmt(std :: move(h)){}
};

数据库打开(char const * path){
:: sqlite3 * db = nullptr;
perror(:: sqlite3_open(path,& db));

返回数据库(db,:: sqlite3_close);
}

语句prepare(database db,std :: string const& sql){
return statement :: prepare(db,sql);
}
}

// FILE:sqliteDB实现文件
#include< boost / property_tree / json_parser.hpp>
#include< boost / property_tree / ptree.hpp>

void sqliteDB :: load(){
using namespace sqlpp;

auto stmt = prepare(open(/ tmp / database.db),SELECT ID,CODE FROM SiteCode;);

while(stmt.step()== SQLITE_ROW)
_records.emplace_back(stmt.column_int(0),stmt.column_int(1));
}

void sqliteDB :: writeJson(std :: ostream& os)const {
using namespace boost :: property_tree;
ptree pt;

for(auto& entry:_records)
pt.put(std :: to_string(entry.id),entry.code);

write_json(os,pt,false);
}

// FILE:main程序
template< typename List>
static void printList(List const& list){
int s = list.size();
std :: cout<< 记录数是:< s<< \\\
;

for(auto& r:list)std :: cout<< r<< ;
}

void dump(sqliteDB const& db){
printList(db.get());
std :: cout<< \\\
============== [AS JSON] =============== \\\
;
db.writeJson(std :: cout);
}

int main(){
sqliteDB db;

std :: cout<< before loading:\\\
;
dump(db);

std :: cout<< 加载后:\\\
;
db.load();
dump(db);
}

只需编译为 g ++ -std = c ++ 11 -g -Wall -Wextra -pedantic main.cpp -lsqlite3 并获取:

  desktop:/ tmp $ sqlite3 database.db<< create table SiteCode(id int primary key,code int); 
sehe @ desktop:/ tmp $ for a in {1..10}; do echoinsert into SiteCode(ID,CODE)VALUES($ a,$ RANDOM);;完成| sqlite3 database.db
sehe @ desktop:/ tmp $ ./test

输出



 在装载之前:
记录数为:0

====== ======== [AS JSON] ===============
{}
装载后:
记录数为: 10
(1,5591)(2,31578)(3,30641)(4,4850)(5,1628)(6,5133)(7,8798)(8,20601)(9,21213) (10,18222)
============== [AS JSON] ===============
{1 :5591,2:31578,3:30641,4:4850,5:1628,6:5133 8798,8:20601,9:21213,10:18222}


okay, so I am banging my head on this for last couple of days but still I am unable to get it right. I have a std::list container and I want to serialize it into JSON string so that I can send it over network.

NOTE: I compile my code using following:

g++ -std=c++11 -o main main.cpp DBAccess11.cpp -lsqlite3 -lboost_serialization

I took help of this and this

Below is my DBAccess1.h file.

#ifndef DBAccess1_HH  
#define DBAccess1_HH

#include <list> // I have deleted some header for sake of readability
#include <boost/serialization/list.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using namespace std;
using boost::property_tree::ptree;
using boost::property_tree::read_json;
using boost::property_tree::write_json;
using boost::property_tree::basic_ptree;

//================================//   
struct SiteCode
{
      int siteID;
      int siteCode;
};

inline ostream& operator<< (ostream &out, SiteCode &site)
{
    out << "(" << site.siteID << "," << site.siteCode << ")";
    return out;
}
//================================//

class sqliteDB {
    list<SiteCode> Site_Code_list;
public:
    list<SiteCode> GET_ALL_Site_Code();
    void printList();
};
#endif**

Below is the DBAccess11.cpp file where all the functions are defined

#include <list> // I have deleted some header for sake of readability
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/serialization/list.hpp>
#include "DBAccess1.h"

using boost::property_tree::ptree;
using boost::property_tree::read_json;
using boost::property_tree::write_json;
using boost::property_tree::basic_ptree;

list<SiteCode> sqliteDB::GET_ALL_Site_Code()
{
        sqlite3 *db;
        const char *sql;
        sqlite3_stmt * stmt;

        int rc = sqlite3_open("/path/to/database.db", &db);
        sql = "SELECT * FROM SiteCode;";       
        rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);

    while(sqlite3_step(stmt)==SQLITE_ROW) {

            int A  = sqlite3_column_int(stmt, 0);
            int B = sqlite3_column_int(stmt, 1);

            SiteCode info;
            info.siteID = A;
            info.siteCode = B;              

            cout<<"Preparing to push data into List"<<endl;
            Site_Code_list.push_back(info);
            cout<<"Data was pushed successfully"<<endl;

            ptree pt;
            for (auto& entry: list<SiteCode> Site_Code_list)  //<< ERROR LINE80
            pt.put(entry.siteID, entry.siteCode);
            std::ostringstream buf; 
            write_json (buf, pt, false); 
            cout<< buf.str() << endl;
    }

    sqlite3_finalize(stmt);
    sqlite3_close(db);
    return Site_Code_list;
}
//====================================================//
void sqliteDB::printList()
{
     int s = Site_Code_list.size();
     cout << "The size of List is :" << s << endl;
     for( list<SiteCode> :: iterator it = Site_Code_list.begin(); it !=  Site_Code_list.end(); it++)     
     cout << *it << " ";
}

Below is main.cpp

#include <list> // I have deleted some header for sake of readability
#include <boost/serialization/list.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using namespace std;
using boost::property_tree::ptree;
using boost::property_tree::read_json;
using boost::property_tree::write_json;
using boost::property_tree::basic_ptree;

int main()
{
    sqliteDB object1;
    object1.GET_ALL_Site_Code();
    object1.printList();
    cout << "\n\nAll the statement were executed properly\n\n";
    return 0;
}

The error I get is as follows:

DBAccess11.cpp: In member function ‘std::list<SiteCode> sqliteDB::GET_ALL_Site_Code()’:
DBAccess11.cpp:80:38: error: expected primary-expression before ‘Site_Code_list’
 for (auto& entry: list<SiteCode> Site_Code_list)
                                  ^
DBAccess11.cpp:80:38: error: expected ‘)’ before ‘Site_Code_list’
DBAccess11.cpp:80:52: error: expected ‘;’ before ‘)’ token
 for (auto& entry: list<SiteCode> Site_Code_list)
                                                ^

My Questions:

(1)Is this the right way to convert std::list into JSON using boost ? if NO then how should it be done ? (Note- I can only use boost and no other library )

(2) If my approach is right then what changes shall I make to correct it ?

解决方案

Paths in your tree are always strings. The compiler will tell you this in the remainder of the message. Arguably the documentation is a more readable source:

Both key_type and data_type are configurable, but will usually be std::string here

The self_type & put(const path_type & path, const Type & value, Translator tr);

So the essence of the fix is

pt.put(std::to_string(entry.id), entry.code);

I got a little bit side-tracked cleaning up the code, so here goes:

Self Contained Sample

// FILE: some header
#include <ostream>

struct SiteCode {
    int id;
    int code;

    SiteCode(int id, int code) : id(id), code(code)
    { }

    friend inline std::ostream &operator<<(std::ostream &out, SiteCode const& site) {
        return out << "(" << site.id << "," << site.code << ")";
    }
};

#include <list> // I have deleted some header for sake of readability

// FILE: sqliteDB header
class sqliteDB {
    using Records = std::list<SiteCode>;
    Records _records;

  public:
    void load();
    Records const& get() const { return _records; }
    void printList() const;
    void writeJson(std::ostream& os) const;
};

// FILE: some sqlpp.hpp utility header (inline implementations only)
#include <memory>
#include <sqlite3.h>

namespace sqlpp {
    using database  = std::shared_ptr<::sqlite3>;

    void perror(int rc) {
        if (rc != SQLITE_OK) throw std::runtime_error(::sqlite3_errstr(rc));
    }

    struct statement {
        static statement prepare(database db, std::string const& sql) {
            ::sqlite3_stmt* stmt = nullptr;
            perror(::sqlite3_prepare_v2(db.get(), sql.c_str(), -1, &stmt, 0));

            return { handle(stmt, ::sqlite3_finalize), db };
        }

        int step()            { return ::sqlite3_step(_stmt.get()); }
        int column_int(int c) { return ::sqlite3_column_int(_stmt.get(), c); }
      private:
        using handle = std::shared_ptr<::sqlite3_stmt>;
        database _db; // keeping it around for the lifetime of _stmt
        handle _stmt;

        statement(handle&& h, database& db) : _db(db), _stmt(std::move(h)) { }
    };

    database open(char const* path) {
        ::sqlite3* db = nullptr;
        perror(::sqlite3_open(path, &db));

        return database(db, ::sqlite3_close);
    }

    statement prepare(database db, std::string const& sql) {
        return statement::prepare(db, sql);
    }
}

// FILE: sqliteDB implementation file
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>

void sqliteDB::load() {
    using namespace sqlpp;

    auto stmt = prepare(open("/tmp/database.db"), "SELECT ID, CODE FROM SiteCode;");

    while (stmt.step() == SQLITE_ROW)         
        _records.emplace_back(stmt.column_int(0), stmt.column_int(1));
}

void sqliteDB::writeJson(std::ostream& os) const {
    using namespace boost::property_tree;
    ptree pt;

    for (auto &entry : _records)
        pt.put(std::to_string(entry.id), entry.code);

    write_json(os, pt, false);
}

// FILE: main program
template <typename List>
static void printList(List const& list) {
    int s = list.size();
    std::cout << "The number of Records is: " << s << "\n";

    for (auto& r : list) std::cout << r << " ";
}

void dump(sqliteDB const& db) {
    printList(db.get());
    std::cout << "\n==============[ AS JSON ]===============\n";
    db.writeJson(std::cout);
}

int main() { 
    sqliteDB db;

    std::cout << "before loading: \n";
    dump(db);

    std::cout << "after loading: \n";
    db.load();
    dump(db);
}

Just compile as g++ -std=c++11 -g -Wall -Wextra -pedantic main.cpp -lsqlite3 and get:

sehe@desktop:/tmp$ sqlite3 database.db <<< "create table SiteCode (id int primary key, code int);"
sehe@desktop:/tmp$ for a in {1..10}; do echo "insert into SiteCode(ID,CODE) VALUES($a, $RANDOM);"; done | sqlite3 database.db 
sehe@desktop:/tmp$ ./test

Output

before loading: 
The number of Records is: 0

==============[ AS JSON ]===============
{}
after loading: 
The number of Records is: 10
(1,5591) (2,31578) (3,30641) (4,4850) (5,1628) (6,5133) (7,8798) (8,20601) (9,21213) (10,18222) 
==============[ AS JSON ]===============
{"1":"5591","2":"31578","3":"30641","4":"4850","5":"1628","6":"5133","7":"8798","8":"20601","9":"21213","10":"18222"}

这篇关于使用boost ptree将std :: list序列化为json的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆