Poco C ++ creates nested JSON objects

I have a nested JSON object. I am trying to build it in a function and add an internal object to the original, but I cannot extract the result.

void build_object (Poco::JSON::Object * const result) { /* Construct some int/bool/string fields here */ Poco::JSON::Object inner; inner.set("some_number", 5); inner.set("some_string", "xyz"); /* This is where it breaks down */ std::string key = "new_object"; result->set("new_object", inner); /* Then some debugging and testing */ // The new object is printed inside the first -> seems like it working result->stringify(std::cout); printf("result has(key): %i\n", result->has(key)); // true printf("isObject: %i\n", result->isObject(key)); // false - huh? printf("isNull: %i\n", result->isNull(key)); // false printf("isArray: %i\n", result->isArray(key)); // false Poco::JSON::Object::Ptr ptr = result->getObject(key); // unsurpisingly fails since the above indicates it not an object printf("ptr isNull: %i\n", ptr.isNull()); // true // ptr->has("some_number"); // throws NullPointerException // if it not an object/null/array, it must be a value Poco::Dynamic::Var v = result->get(key); // at least one of these things should be true, otherwise what is it? printf("var isString: %i\n", v.isString()); // false printf("var isStuct: %i\n", v.isStruct()); // false printf("var isEmpty: %i\n", v.isEmpty()); // false printf("var isArray: %i\n", v.isArray()); // false printf("var isSigned: %i\n", v.isSigned()); // false printf("var isNumeric: %i\n", v.isNumeric());// false } 

So, I have an internal object that is correctly placed in the result, it is printed using stringify with all the correct values, and the result is → has (). But, according to the result, it is not an object, an array, or zero, so you can get it with var. But, once it is obtained from var, it is not a string, structure, array or number, nor is it empty. The inner object seems to exist and does not exist at the same time.

So how do I put this object in my result? And how do I get this?

thanks

note: I saw this topic Proper use of POS-C ++ JSON for data analysis , but it builds a JSON object from a string and then parses it. I suppose I could build everything as a string and convert to a Poco object in the last step, but I'm still wondering why this is happening. Also, using result-> set () and result-> get () is a cleaner, less hack-y solution than going through a string.

Links: Poco JSON Doc , Poco Dynamic Var Doc

+6
source share
2 answers

Poco :: Objects and JSON arrays are stored as shared pointers by default (optimization to avoid copying values), and all this is Dynamic :: Var, so it works for both pointers and values. When you insert an object as a value, it works because Dynamic :: Var will store almost everything, but the problem that you experience when checking it comes from the fact that the internal comparison does not return true for Object values ​​because it compares only with the default type - Poco :: SharedPtr <Poco :: JSON :: Object>.

Here's a workaround:

 void build_object (Poco::JSON::Object * const result) { // smart pointer, so don't worry about cleaning up Poco::JSON::Object::Ptr inner = new Poco::JSON::Object; inner->set("some_number", 5); inner->set("some_string", "xyz"); std::string key = "new_object"; result->set(key, inner); printf("isObject: %i\n", result->isObject(key)); // true } 

I uncovered a github issue to ease this caveat.

+7
source

I am trying to create a json file with a nested object using the poco library. Finally, it can be done with Poco :: Json :: Array.

Please find the published sinippet code. Hope this helps. Json output is attached to the post.

 #include "Poco\JSON\JSON.h" #include "Poco\JSON\Stringifier.h" #include "Poco\JSON\Object.h" #include "Poco\Dynamic\Var.h" using namespace std; using Poco::JSON::Stringifier; using Poco::JSON::Object; using Poco::JSON::Array; void makeJsonNestedObject() { Object RootObj(true); Array FLArray; for(int i=0; i<3; i++) { Object::Ptr FirstLevelArrayNode = new Poco::JSON::Object(true); TCHAR strNameBuff[15]; _stprintf(strNameBuff, _T("%s_%d"),_T("Servername"),i); std::basic_string<TCHAR> strName = strNameBuff; FirstLevelArrayNode->set("HostName", strName); FirstLevelArrayNode->set("Overall Impact", "Dummy Data"); Array SLArray; for(int j=0; j<3;j++) { Object::Ptr SecondLevelArrayNode = new Poco::JSON::Object(true); TCHAR attr1NameBuff[15]; TCHAR attr2NameBuff[15]; _stprintf(attr1NameBuff, _T("%s_%d"),_T("AttrOne"),j); _stprintf(attr2NameBuff, _T("%s_%d"),_T("AttrTwo"),j); std::basic_string<TCHAR> attr1Name = attr1NameBuff; std::basic_string<TCHAR> attr2Name = attr2NameBuff; SecondLevelArrayNode->set("Attribute", attr1Name); SecondLevelArrayNode->set("SubAttribute", attr2Name); Poco::Dynamic::Var obj(SecondLevelArrayNode); SLArray.add(obj); } FirstLevelArrayNode->set("Attribute_Details",SLArray); Poco::Dynamic::Var FLArrayNodeobj(FirstLevelArrayNode); FLArray.add(FLArrayNodeobj); } std::ostringstream os; std::cout <<"before stringlify.." << std::endl; FLArray.stringify(os, 2); std::cout << os.str() << std::endl; } 

Json Output:

  [ { "HostName" : "Servername_0", "Overall Impact" : "Dummy Data", "Attribute_Details" : [ { "Attribute" : "AttrOne_0", "SubAttribute" : "AttrTwo_0" }, { "Attribute" : "AttrOne_1", "SubAttribute" : "AttrTwo_1" }, { "Attribute" : "AttrOne_2", "SubAttribute" : "AttrTwo_2" } ] }, { "HostName" : "Servername_1", "Overall Impact" : "Dummy Data", "Attribute_Details" : [ { "Attribute" : "AttrOne_0", "SubAttribute" : "AttrTwo_0" }, { "Attribute" : "AttrOne_1", "SubAttribute" : "AttrTwo_1" }, { "Attribute" : "AttrOne_2", "SubAttribute" : "AttrTwo_2" } ] }, { "HostName" : "Servername_2", "Overall Impact" : "Dummy Data", "Attribute_Details" : [ { "Attribute" : "AttrOne_0", "SubAttribute" : "AttrTwo_0" }, { "Attribute" : "AttrOne_1", "SubAttribute" : "AttrTwo_1" }, { "Attribute" : "AttrOne_2", "SubAttribute" : "AttrTwo_2" } ] } ] 
+2
source

Source: https://habr.com/ru/post/983475/


All Articles