Edited to simplify and show my EXACT code.
I have the following data that I need to serialize to JSON as well as parse from JSON.
string name;
std::map<string, string> metaData;
I need the JSON to be nested/hierarchical like this:
{
"name":"john smith"
"metadata":
{
"age":45,
"middle_name":"william",
},
}
Here is my EXACT code:
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();
}
}
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;
}