【问题标题】:Boost Property Tree: Where have my escape sequences gone in JSON String?Boost 属性树:我的转义序列在 JSON 字符串中去了哪里?
【发布时间】:2015-06-02 06:25:34
【问题描述】:

我正在使用 boost 来创建 JSON 字符串。我正在尝试通过 http POST 将此 JSON 字符串发送到服务器。

下面是Boost创建的字符串

{"TokenNo":"ABC123456","CPUID":"ABC123456","CommandID":"09","IsEncrypted":"0","CommandString:[{"ADD":"97","ESTBCODE":"99999999","EID":"XY","CID":"0154400000","DATE":"14042015","TIME":"1835","IOMODE":"I","REASONCODE":"55","LAT":"87","LONG":"90"}, {"ADD":"87","ESTBCODE":"99999998","EID":"XX","CID":"0154300000","DATE":"15052015","TIME":"1947","IOMODE":"O","REASONCODE":"54","LAT":"89","LONG":"91"}]}

上面的 json 字符串是我对 previous question 的回答所期望的。但是在形成正确的 json 数组后,我仍然无法发送这个字符串。

服务器需要以下格式的 JSON 字符串:

{"TokenNo":"ABC123456","CPUID":"ABC123456","CommandID":"09","IsEncrypted":"0","CommandString:[{\"ADD\":\"97\",\"ESTBCODE\":\"99999999\",\"EID\":\"XY\",\"CID\":\"0154400000\",\"DATE\":\"14042015\",\"TIME\":\"1835\",\"IOMODE\":\"I\",\"REASONCODE\":\"55\",\"LAT\":\"87\",\"LONG\":\"90\"}, {\"ADD\":\"87\",\"ESTBCODE\":\"99999998\",\"EID\":\"XX\",\"CID\":\"0154300000\",\"DATE\":\"15052015\",\"TIME\":\"1947\",\"IOMODE\":\"O\",\"REASONCODE\":\"54\",\"LAT\":\"89\",\"LONG\":\"91\"}]}  

所需的“\”在哪里?

下面是我的 DBAccess.cpp 文件

using namespace boost::property_tree;
ptree pt;
ptree pt1;
ptree pt2;

//===============XX==============XX================//

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

          /*-----
          Code to access Database
            ------*/


        sqlite3_finalize(stmt);
        sqlite3_close(db);

        return AttendanceT_list;
}

//===============XX==============XX================//

void sqliteDB::writeJson(std::ostream& os) const {

    for (auto &entry : AttendanceT_list) 
    {       
            pt.put("ADD", entry.Atten_Addr);
            pt.put("ESTBCODE", entry.Atten_EstablishmentCode);
            pt.put("EID", entry.Atten_EmployeeID);
            pt.put("CID", entry.Atten_CardID);
            pt.put("DATE", entry.Atten_PunchDate);
            pt.put("TIME", entry.Atten_PunchTime);
            pt.put("IOMODE", entry.Atten_InOutMode);
            pt.put("REASONCODE", entry.Atten_ReasonCode);
            pt.put("LAT", entry.Atten_Lat);
            pt.put("LONG", entry.Atten_Long);

            pt1.push_back(ptree::value_type("", pt));               
    } 

    write_json(os, pt1, false);


}//Function ends here

//===============XX==============XX================//

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

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

//===============XX==============XX================//

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

    std::ofstream file("output1.txt");
 // db.writeJson(file);

    ifstream myReadFile;
    myReadFile.open("output1.txt");
    string output1;
    if (myReadFile.is_open()) 
    {
          while (!myReadFile.eof())
          {
                myReadFile >> output1;
          }
    }

 myReadFile.close();

 return output1;
}

//===============XX==============XX================//

std::string sqliteDB::to_json(POST3 const& o)
{
        pt2.put("TokenNo", o.TokenNo);
        pt2.put("CPUID", o.CPUID);
        pt2.put("CommandID", o.CommandID);
        pt2.put("IsEncrypted", o.IsEncrypted);
        pt2.push_back(ptree::value_type("CommandString", pt1));

        std::ostringstream oss;
        boost::property_tree::write_json(oss, pt2, false);

        std:: string json;
        json = oss.str();


    //=======SENDING(POSTING) DATA TO THE SERVER USING BOOST ASIO======//

      try{/*-----Code of HTTP POST------*/}

      catch (std::exception& e){ }

    return oss.str();
}

//===============XX==============XX================//

以下是DbAccess.h文件的内容

//=========================//

struct AttendanceT
{
  string Atten_Addr;
  string Atten_EstablishmentCode;
  string Atten_EmployeeID;
  string Atten_CardID;
  string Atten_PunchDate;
  string Atten_PunchTime;
  string Atten_InOutMode;
  string Atten_ReasonCode;
  string Atten_Lat; 
  string Atten_Long; 
};

struct POST3
{
    public:
    std::string TokenNo;
    std::string CPUID;
    std::string CommandID;
    std::string IsEncrypted;
    std::string JSON_Cmnd_String;
};

//=========================//

class sqliteDB {

    public:
     //---
        some other function declaration
     ----//

    void printList(List const& list);
    string dump(sqliteDB const& db);
    string to_json(POST3 const& o);
};

这是 ma​​in.cpp 文件

int main()
{
     sqliteDB object1;

     object1.GET_Attendance();
     object1.dump(object1);

     POST3 obj { "ABC123456", "ABC123456", "09", "0" /*,object1.dump(object1)*/};

     cout << "\nAll the statement were executed properly\n\n\n";

     return 0;
 }

我参考了这个资源here

我相信我在创建 json 字符串时犯了一些错误,但我不确定具体在哪里。

更新

boost 文档说:

属性树数据集没有类型,不支持数组。因此,使用了以下 JSON / 属性树映射:

  • JSON 对象映射到节点。每个属性都是一个子节点。
  • JSON 数组映射到节点。每个元素都是一个名称为空的子节点。如果一个节点同时具有已命名和未命名的子节点,则无法将其映射到 JSON 表示。
  • JSON 值映射到包含该值的节点。但是,所有类型信息都丢失了;数字以及文字“null”、“true”和“false”都简单地映射到它们的字符串形式。
  • 无法映射同时包含子节点和数据的属性树节点。

那么,这是否意味着 Boost 不完全符合 JSON 标准??

请指导我。谢谢

【问题讨论】:

  • Boost 没有 JSON 解析器。 Boost Property Tree 是一个属性树库。
  • @sehe 你有什么建议?我获得所需 JSON 格式的最佳方法是什么?
  • 我会聘请一位称职的程序员。严重地。我正在写一个答案,但你几个月来一直在问这个任务的问题,而且情况并没有好转。我建议开始更简单。并在 python 或类似工具中执行此操作。
  • 正如@sehe 建议的那样,使用更简单的方法,即仅标头rapidjson 另一个有用的工具是JSONLint,您可以在其中验证您的json 字符串。

标签: c++ json boost boost-propertytree


【解决方案1】:
  • 什么服务器需要这个?因为它不是 JSON:字符串 "CommandString:[{\"AD... 永远不会结束,因此数组和包含对象不完整/未关闭。

  • 虽然不是第一位(“Boost 创建的字符串”):

    "CommandString:[{"ADD"
    

    不是有效的对象属性(属性名称后面没有:)。


问。必需的“\”在哪里?

我很确定你还需要其他东西:

{"TokenNo":"ABC123456","CPUID":"ABC123456","CommandID":"09","IsEncrypted":"0","CommandString":[{"ADD":"97","ESTBCODE":"99999999","EID":"XY","CID":"0154400000","DATE":"14042015","TIME":"1835","IOMODE":"I","REASONCODE":"55","LAT":"87","LONG":"90"}, {"ADD":"87","ESTBCODE":"99999998","EID":"XX","CID":"0154300000","DATE":"15052015","TIME":"1947","IOMODE":"O","REASONCODE":"54","LAT":"89","LONG":"91"}]}

或者,漂亮的印刷品:

{
    "TokenNo": "ABC123456",
    "CPUID": "ABC123456",
    "CommandID": "09",
    "IsEncrypted": "0",
    "CommandString": [{
        "ADD": "97",
        "ESTBCODE": "99999999",
        "EID": "XY",
        "CID": "0154400000",
        "DATE": "14042015",
        "TIME": "1835",
        "IOMODE": "I",
        "REASONCODE": "55",
        "LAT": "87",
        "LONG": "90"
    },
    {
        "ADD": "87",
        "ESTBCODE": "99999998",
        "EID": "XX",
        "CID": "0154300000",
        "DATE": "15052015",
        "TIME": "1947",
        "IOMODE": "O",
        "REASONCODE": "54",
        "LAT": "89",
        "LONG": "91"
    }]
}

Live On Coliru

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <iostream>

using Tree = boost::property_tree::ptree;

struct AttendanceT {
    std::string Addr;
    std::string EstablishmentCode;
    std::string EmployeeID;
    std::string CardID;
    std::string PunchDate;
    std::string PunchTime;
    std::string InOutMode;
    std::string ReasonCode;
    std::string Lat;
    std::string Long;

    Tree to_tree() const {
        Tree pt;
        pt.put("ADD",        Addr);
        pt.put("ESTBCODE",   EstablishmentCode);
        pt.put("EID",        EmployeeID);
        pt.put("CID",        CardID);
        pt.put("DATE",       PunchDate);
        pt.put("TIME",       PunchTime);
        pt.put("IOMODE",     InOutMode);
        pt.put("REASONCODE", ReasonCode);
        pt.put("LAT",        Lat);
        pt.put("LONG",       Long);

        return pt;
    }
};

struct POST3 {
    std::string TokenNo;
    std::string CPUID;
    std::string CommandID;
    std::string IsEncrypted;

    std::vector<AttendanceT> AttendanceT_list;

    Tree to_tree() const {
        boost::property_tree::ptree pt;
        pt.put("TokenNo",     TokenNo);
        pt.put("CPUID",       CPUID);
        pt.put("CommandID",   CommandID);
        pt.put("IsEncrypted", IsEncrypted);

        auto& CommandString = pt.put_child("CommandString", {});

        for (auto& obj : AttendanceT_list) 
            CommandString.push_back({ "", obj.to_tree() });

        return pt;
    }
};

static inline std::string to_string(Tree const& tree) {
    std::ostringstream oss;
    boost::property_tree::write_json(oss, tree);
    return oss.str();
}

int main()
{
    std::vector<AttendanceT> list = {
        { "97", "99999999", "XY", "0154400000", "14042015", "1835", "I", "55", "87", "90" },
        { "87", "99999998", "XX", "0154300000", "15052015", "1947", "O", "54", "89", "91" },
    };

    POST3 obj { "ABC123456", "ABC123456", "09", "0", list };

    std::cout << to_string(obj.to_tree());
}

如果你真的想要它

你可以替换

auto& CommandString = pt.put_child("CommandString", {});

for (auto& obj : AttendanceT_list) 
    CommandString.push_back({ "", obj.to_tree() });

通过

Tree CommandString;

for (auto& obj : AttendanceT_list) 
    CommandString.push_back({ "", obj.to_tree() });

pt.put("CommandString", to_string(CommandString));

另见: Live On Coliru

打印

{
    "TokenNo": "ABC123456",
    "CPUID": "ABC123456",
    "CommandID": "09",
    "IsEncrypted": "0",
    "CommandString": "{\n    \"\": {\n        \"ADD\": \"97\",\n        \"ESTBCODE\": \"99999999\",\n        \"EID\": \"XY\",\n        \"CID\": \"0154400000\",\n        \"DATE\": \"14042015\",\n        \"TIME\": \"1835\",\n        \"IOMODE\": \"I\",\n        \"REASONCODE\": \"55\",\n        \"LAT\": \"87\",\n        \"LONG\": \"90\"\n    },\n    \"\": {\n        \"ADD\": \"87\",\n        \"ESTBCODE\": \"99999998\",\n        \"EID\": \"XX\",\n        \"CID\": \"0154300000\",\n        \"DATE\": \"15052015\",\n        \"TIME\": \"1947\",\n        \"IOMODE\": \"O\",\n        \"REASONCODE\": \"54\",\n        \"LAT\": \"89\",\n        \"LONG\": \"91\"\n    }\n}\n"
}

【讨论】:

    猜你喜欢
    • 2016-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    • 1970-01-01
    相关资源
    最近更新 更多