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



编辑,以简化和显示我的确切代码。

我有以下数据,我需要序列化到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();
    }
}

更新:在整理这个例子时,我发现了一个微妙的错误;在即将发布的1.6.1和1.7.0版本的仓库中修复了这个问题。下面的示例在早期版本中可以正常工作,只是不要在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;
}

方法如下:

// 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不能用于嵌套字段

最新更新