使用 JSON boost 序列化创建 JSON 字符串时如何获取名称-值对?
how get name-value pair when creating JSON string from using JSON boost serialization?
在回答这个问题之前,我想请各位好心人先看看我目前得到的 输出。输出是从 sqlite3 table SiteCode 中获取的,它有两列 ID 和 Code .
虽然,我去了输出,但我仍然没有在输出中看到字段名称。
我的意思是我需要一个如下所示的输出(名称-值对)
{"ID":"7","Code":"786","ID":"8","Code":"78","ID":"9","Code":"785","ID":"10","Code":"998","ID":"11","Code":"656"}
那么我是将 boost-name-value-pair 与解析器一起使用,还是需要对现有代码进行更改?怎么样?
我的最终目标是使用 HTTP POST 方法通过网络发送此 JSON 名称-值字符串。
如果你能指导我解决这个问题,我将不胜感激。如果可能的话,你能给我举一些例子吗?
下面是我现在编写该循环的方式:
for (auto &entry : _records) {
ptree obj;
obj.put("ID", entry.id);
obj.put("CODE", entry.code);
pt.insert(pt.end(), { "", obj });
}
替代拼写:
pt.push_back(ptree::value_type("", obj));
编辑 当然,如果您真的想要您问题的确切输出格式, 你会做
for (auto &entry : _records) {
pt.add("ID", entry.id);
pt.add("CODE", entry.code);
}
但我看不出这种格式有什么用,因为您会得到各种重复的属性(这不是标准的 JSON)并且依赖于属性的顺序(可能不支持所有读者)。
又是我的测试:
$ sqlite3 database.db <<<"create table sitecode(id int primary key, code int);"
$ for a in {1..10}; do echo "insert into sitecode(id,code) values($a, $RANDOM);"; done | sqlite3 database.db
$ ./test
我得到:
before loading:
The number of Records is: 0
==============[ AS JSON ]===============
{}
after loading:
The number of Records is: 10
(1,24080) (2,9982) (3,3129) (4,5337) (5,23554) (6,3581) (7,32306) (8,12024) (9,9161) (10,27641)
==============[ AS JSON ]===============
{"":{"ID":"1","CODE":"24080"},"":{"ID":"2","CODE":"9982"},"":{"ID":"3","CODE":"3129"},"":{"ID":"4","CODE":"5337"},"":{"ID":"5","CODE":"23554"},"":{"ID":"6","CODE":"3581"},"":{"ID":"7","CODE":"32306"},"":{"ID":"8","CODE":"12024"},"":{"ID":"9","CODE":"9161"},"":{"ID":"10","CODE":"27641"}}
完整演示
// 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) {
ptree obj;
obj.put("ID", entry.id);
obj.put("CODE", entry.code);
pt.insert(pt.end(), { "", obj });
}
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);
}
只需将其编译为单一源代码
在回答这个问题之前,我想请各位好心人先看看我目前得到的
虽然,我去了输出,但我仍然没有在输出中看到字段名称。 我的意思是我需要一个如下所示的输出(名称-值对)
{"ID":"7","Code":"786","ID":"8","Code":"78","ID":"9","Code":"785","ID":"10","Code":"998","ID":"11","Code":"656"}
那么我是将 boost-name-value-pair 与解析器一起使用,还是需要对现有代码进行更改?怎么样?
我的最终目标是使用 HTTP POST 方法通过网络发送此 JSON 名称-值字符串。
如果你能指导我解决这个问题,我将不胜感激。如果可能的话,你能给我举一些例子吗?
下面是我现在编写该循环的方式:
for (auto &entry : _records) {
ptree obj;
obj.put("ID", entry.id);
obj.put("CODE", entry.code);
pt.insert(pt.end(), { "", obj });
}
替代拼写:
pt.push_back(ptree::value_type("", obj));
编辑 当然,如果您真的想要您问题的确切输出格式, 你会做
for (auto &entry : _records) {
pt.add("ID", entry.id);
pt.add("CODE", entry.code);
}
但我看不出这种格式有什么用,因为您会得到各种重复的属性(这不是标准的 JSON)并且依赖于属性的顺序(可能不支持所有读者)。
又是我的测试:
$ sqlite3 database.db <<<"create table sitecode(id int primary key, code int);"
$ for a in {1..10}; do echo "insert into sitecode(id,code) values($a, $RANDOM);"; done | sqlite3 database.db
$ ./test
我得到:
before loading:
The number of Records is: 0
==============[ AS JSON ]===============
{}
after loading:
The number of Records is: 10
(1,24080) (2,9982) (3,3129) (4,5337) (5,23554) (6,3581) (7,32306) (8,12024) (9,9161) (10,27641)
==============[ AS JSON ]===============
{"":{"ID":"1","CODE":"24080"},"":{"ID":"2","CODE":"9982"},"":{"ID":"3","CODE":"3129"},"":{"ID":"4","CODE":"5337"},"":{"ID":"5","CODE":"23554"},"":{"ID":"6","CODE":"3581"},"":{"ID":"7","CODE":"32306"},"":{"ID":"8","CODE":"12024"},"":{"ID":"9","CODE":"9161"},"":{"ID":"10","CODE":"27641"}}
完整演示
// 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) {
ptree obj;
obj.put("ID", entry.id);
obj.put("CODE", entry.code);
pt.insert(pt.end(), { "", obj });
}
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);
}
只需将其编译为单一源代码