1

この質問に答える前に、ここにいるすべての善良な人々に、私が現在得ているこの出力を最初に見てください。出力は、 2 つの列IDCodeを持つsqlite3 テーブルSiteCodeからフェッチされます。

ただし、出力に移動しますが、出力にフィールド名が表示されません。つまり、次のような出力が必要です (名前と値のペア)

{"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 の名前と値の文字列をネットワーク経由で送信することです。

これについてご案内いただければ幸いです。可能であれば、いくつかの例を教えてください。

4

1 に答える 1

1

そのループを今書く方法は次のとおりです。

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);
}

単一のソースとしてコンパイルするだけです

于 2015-03-26T12:27:56.173 に答える