How to create and parse hierarchical/nested JSON with Poco C++? How to create and parse hierarchical/nested JSON with Poco C++? json json

How to create and parse hierarchical/nested JSON with Poco C++?


UPDATE: while putting together this example, I found a subtle bug; it is fixed in the repo for upcoming 1.6.1 and 1.7.0 release. The sample below works fine with earlier releases, just don't use preserve order with JSON::Stringifier::stringify() (using Object::stringify() is fine).

Here you go; if you don't care about preserving JSON entries insertion order, don't pass anything to Object constructor - it will perform slightly better:

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


Here's what worked:

// Deserialize from JSONvoid 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();}

It would appear DynamicStruct cannot be used for nested fields.