如何使用Poco C ++创建和解析分层/嵌套JSON?

时间:2015-05-14 22:49:58

标签: json c++11 poco-libraries

编辑以简化并显示我的精确代码。

我有以下数据需要序列化为JSON以及从JSON解析。

string name;
std::map<string, string> metaData;

我需要将JSON嵌套/分层,如下所示:

{
    "name":"john smith"
    "metadata":
    {
        "age":45,
        "middle_name":"william",
    },
}

这是我的精确代码:

void DeserializeFromJSON(string &jsonString)
{
    // Parse the JSON
    Poco::JSON::Parser jsonParser;
    Poco::Dynamic::Var parsedJSON = jsonParser.parse(jsonString);
    Poco::Dynamic::Var parsedResult = jsonParser.result();

    // Extract the JSON Object
    Poco::DynamicStruct jsonStruct = *parsedResult.extract<Poco::JSON::Object::Ptr>();

    // Get the name
    name = jsonStruct["name"].toString();

    // Get the meta data -- which of these should I use???
    Poco::Dynamic::Var metaVar = jsonStruct["metadata"];
    Poco::JSON::Object metaObj = jsonStruct["metadata"];

    // At this point, exactly what is it I have in 'metaVar' and 'metaObj'?

    // If I try to loop like you say, I get compiler error C2664 in "var.h"
    for (Poco::JSON::Object::ConstIterator itr = jsonObject.begin(), end = jsonObject.end(); itr != end; ++itr)
    {
        string metaName = itr->first;
        string metaValue = itr->second.toString();
    }
}

2 个答案:

答案 0 :(得分:5)

更新:在整理这个例子时,我找到了a subtle bug;它将在即将发布的1.6.1和1.7.0版本的repo中修复。下面的示例适用于早期版本,只是不要使用保留顺序与JSON :: Stringifier :: stringify()(使用Object :: stringify()很好)。

你走了;如果您不关心保留JSON条目的插入顺序,请不要将任何内容传递给Object构造函数 - 它会稍微好一些:

#include "Poco/JSON/Parser.h"
#include "Poco/JSON/ParseHandler.h"
#include "Poco/JSON/Stringifier.h"

using Poco::JSON::ParseHandler;
using Poco::JSON::Stringifier;
using Poco::JSON::Object;
using Poco::JSON::Parser;
using Poco::Dynamic::Var;
using Poco::DynamicStruct;

void objPrint(Object& obj, const std::string& name = "")
{
    for (Object::ConstIterator it = obj.begin(),
        end = obj.end(); it != end; ++it)
    {
        if (!name.empty()) std::cout << name << ':';
        std::cout << it->first << ':';
        if (it->second.type() == typeid(Object::Ptr))
        {
            Object::Ptr p = it->second.extract<Object::Ptr>();
            objPrint(*p, it->first);
        }
        else
             std::cout << it->second.toString() << std::endl;
    }
}

int main(int, char**)
{
    typedef std::map<std::string, int> PersonMap;

    std::string timeStamp = "2015-05-14T17:47:21.999Z";
    Poco::Int32 identifier = 3;
    std::string name = "john smith";
    PersonMap metaData;
    metaData.insert(PersonMap::value_type("william", 45));

    Object obj(true);
    obj.set("ts", timeStamp);
    obj.set("name", name);
    obj.set("identifier", identifier);
    Object::Ptr pMD = new Poco::JSON::Object(true);
    for (PersonMap::iterator it = metaData.begin(),
        end = metaData.end(); it != end; ++it)
    {
        pMD->set("middle_name", it->first);
        pMD->set("age", it->second);
    }
    obj.set("metadata", pMD);

    std::ostringstream os;
    obj.stringify(os, 2);
    std::cout << os.str() << std::endl;

    Parser parser;
    Var result = parser.parse(os.str());

    Object::Ptr pObj = result.extract<Object::Ptr>();
    objPrint(*pObj);

    return 0;
}

答案 1 :(得分:0)

以下是有效的:

// Deserialize from JSON
void DeserializeFromJSON(string &jsonString)
{
    // Parse the JSON
    Poco::JSON::Parser jsonParser;
    Poco::Dynamic::Var parsedJSON = jsonParser.parse(jsonString);
    Poco::Dynamic::Var parsedResult = jsonParser.result();

    // Extract top-level fields
    Poco::DynamicStruct jsonStruct = *parsedResult.extract<Poco::JSON::Object::Ptr>();
    name = jsonStruct["identifier"].toString();

    // Get metadata nested fields
    string keyStr = "metadata";
    Poco::JSON::Object::Ptr jsonObject = parsedResult.extract<Poco::JSON::Object::Ptr>();
    Poco::Dynamic::Var metaVar = jsonObject->get(keyStr);
    Poco::JSON::Object::Ptr metaObj = metaVar.extract<Poco::JSON::Object::Ptr>();
    for (Poco::JSON::Object::ConstIterator itr = metaObj->begin(), end = metaObj->end(); itr != end; ++itr)
        metaData[itr->first] = itr->second.toString();
}

看起来DynamicStruct不能用于嵌套字段。