[Solved] Parsing a JSon reply issue
- 
Hi, I'm doing a request to an url which gives me the next Json reply: @ 
 "{"data":"[{"Name":"One","Code":""},{"Name":"Two","Code":"Alpha"}]"}" @I am using Qt 8.4.5 so I have to do it with QNetwork and QScript. So I did the next: @ 
 QNetworkRequest request(_Url);
 QNetworkReply *reply = nam->get(request);QString InfoByteArray = (QString)reply->readAll(); if ( reply->error()== QNetworkReply::NoError) 
 {
 //------------ JSON Parser --------------//QScriptEngine engine; 
 QScriptValue result = engine.evaluate("("+InfoByteArray+")");QScriptValue InfoData= result.property("data"); 
 qDebug() << "InfoData" << InfoData.toString();
 }
 @With that I get all the part on the right of "data": @ 
 [{"Name":"One","Code":""},{"Name":"Two","Code":"Alpha"}]"
 @Now I want to take the Name en Code values ofc but I can't get them, I try doing this but never goes into the while: @ 
 QScriptValueIterator it(InfoData);
 while (it.hasNext())
 {
 it.next();
 QScriptValue entry = it.value();QString name= entry.property("Name").toString(); //this doesnt works QString name2= entry.property("data").property("Name").toString(); //this either} 
 @And if I try doing that out of the while, I just get empty strings : 
 @
 QString name= result.property("Name").toString(); // qDebug() << name; returns ""
 QString name2= entry.property("data").property("Name").toString();
 @So...Any Idea of what am I doing wrong here? Thank you! 
- 
You don't "have to use" Qt script. There are plenty of other parsers out there. "This one":https://github.com/nlohmann/json for instance. Or "this":http://libqxt.bitbucket.org/doc/tip/qxtjson.html one if you want to stay closer to Qt. 
- 
Hi Andre, What I don't understand is why I was able to get a part but not all I need... I mean, I was following this example: "Example":http://www.makina-corpus.org/blog/access-json-webservice-qt-c So the logical thing is that if I got the right-side part of "data", I had to be able to get the next info, right? :P Btw...Thank you, I'll take a look with the second one (dunno how to include the first one on my project still). One quick question about the second one: To use that library I understand that you have to include the Qxt module to the pro: CONFIG += qxt 
 QXT = coreand then: #include <Qxt> But seems tahtmy project still doesnt have the Qxt library (I've run qmake and build it again) 
- 
So I add json.cc and json.h from the first link to my project... I got some errors that I solved but now it says: error: 'using object_t = class std::map<std::basic_string<char>, nlohmann::json>' has no member named 'emplace' In a line in middle of the *.cc.... Isn't there any other way???? 
 Hate when things aren't easy -.-" hehe
- 
Yes, that was the first error i solved. I put it on the .pro file as QMAKE_CXXFLAGS += -std=c++11 
 and tried too with
 QMAKE_CXXFLAGS += -std=gnu++11And the compile output gaves something like: @ 
 g++ -c -pipe -std=c++11 -g -Wall -W -D_REENTRANT -DQT_SCRIPT_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/lib/qt4/mkspecs/linux-g++[...]@
- 
Then I get the same error I had first: /usr/lib/gcc/i686-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options. Which I solved with 
 @
 QMAKE_CXXFLAGS = -std=c++11(and even with the next line instead of the other the error dissapears) 
 QMAKE_CXXFLAGS = -std=gnu+11
 @The error I was saying is in line 197: 
 @
 for (auto& element : a)
 {
 value_.object->emplace(std::make_pair(std::move(element[0]), std::move(element[1]))); // HERE IS THE ERROR
 }
 @
- 
I've found this other solution: "JSon":https://github.com/gaudecker/qt-json It seems that it works but now I can't get the name and code values, I'm trying to do: @ 
 bool ok;QtJson::JsonObject result = QtJson::parse(myJson, ok).toMap(); 
 if(!ok) {
 qFatal("An error occurred during parsing");
 }else
 {
 qDebug() << "data" << result["data"].toString();
 qDebug() << " try1" << result["Name"].toString();QtJson::JsonObject nested = result["data"].toMap(); qDebug() << "try2:" << nested["Name"].toString();@ But try1 and try2 are empy. Any Idea of how to make that work? Thanks! 
- 
Hi, [quote author="roseicollis" date="1423496917"]But try1 and try2 are empy. Any Idea of how to make that work?[/quote]Your data is a JSON array, not a JSON object. 
- 
Oh I see... But if I put: 
 @
 QtJson::JsonArray nested = result["data"].toMap();
 qDebug() << "try2:" << nested["Name"].toString();
 @It says: 
 @
 conversion from 'QMap<QString, QVariant>' to non-scalar type 'QtJson::JsonArray {aka QList<QVariant>}' requested
 @I don't really know how to parse that array... I've tried this too: @ 
 QtJson::JsonObject bbb = QtJson::parse(result["data"].toString(), ok).toMap();
 qDebug() << bbb;
 @
 But it only prints: QMap()So... I'm really stuck there... -.-'' 
- 
Are you familiar with JSON syntax? - represents an array.
- { } represents an object.
 You need to understand your structure first: You have 1 array. That array contains 2 objects. Each object contains 2 strings Extract the objects from the array like this: 
 @
 auto object1 = result[0];
 auto object2 = result[1];
 @After that, you can extract the "Name" and "data" fields from the objects. Remember, arrays are indexed by integers, while objects/maps are indexed by strings. 
- 
Hi JKSH, Ermmm noup, I wasn't familiar with it but now I understand it better :) Thanks! One thing: what is auto for you? O.o a JsonObject? @ 
 QtJson::JsonObject object1 = result[0].toMap(); //object1 returns: QMap()
 QVariant object1 = result[0]; //object1 returns: QVariant(, )
 QVariant object1 = result[0].toString();//object1 returns: QVariant(QString, )
 @EDIT: Didn't know there were something called 'auto' O.o but trying that: @ 
 QtJson::JsonObject result = QtJson::parse(myJson, ok).toMap();
 auto object1 = result[0];
 QtJson::JsonObject trying = QtJson::parse(object1, ok).toMap();
 qDebug() <<" trying msg" << trying;
 @it says: error: no matching function for call to 'parse(QVariant&, bool&)' 
 And if I try with
 @
 QtJson::JsonObject trying = QtJson::parse(object1["Name"], ok).toMap();
 @
 It says: error: no match for 'operator[]' in 'object1["Name"]'
- 
You're welcome. :) [quote author="roseicollis" date="1423567075"] 
 @
 QtJson::JsonObject result = QtJson::parse(myJson, ok).toMap();
 @
 [/quote]2 issues:Like I said before, your data is an array, not an object. So, you should make result a JsonArray, not a JsonObject. Also, toMap() produces an object. You want to use toList() instead, which produces an array.What type is myJson? Your compiler complained because you passed a QVariant into QtJson::parse(). What type does it actually accept? (hint: look inside json.h)[quote author="roseicollis" date="1423567075"]EDIT: Didn't know there were something called 'auto' O.o[/quote]'auto' is a "C++11 keyword":http://geekswithblogs.net/BlackRabbitCoder/archive/2012/03/15/c-little-wonders-the-c11-auto-keyword-redux.aspx. When you use it, the compiler will try to figure out the variable's type automatically. 
- 
Hi again ^^ [quote author="JKSH" date="1423568300"] 
 Like I said before, your data is an array, not an object. So, you should make result a JsonArray, not a JsonObject. Also, toMap() produces an object. You want to use toList() instead, which produces an array.
 [/quote]
 Didn't know that it creates an object too... (anyway i tried before with strings and bytearray hopeing something works hahaha but not obviously)[quote author="JKSH" date="1423568300"] 
 What type is myJson? Your compiler complained because you passed a QVariant into QtJson::parse(). What type does it actually accept? (hint: look inside json.h)
 [/quote]myJson is a QString: 
 @
 QNetworkRequest request(_Url);
 QNetworkReply *reply = nam->get(request);
 QString myJson = (QString)reply->readAll();
 @I know that this error is because of the types but I was thinking that it takes Variants and now saw that not. The definition of parse is: 
 @
 QVariant parse(const QString &json, bool &success);
 @If I try with: 
 @
 QtJson::JsonArray result = QtJson::parse(myJson, ok).toList();
 qDebug() << " a " << result;
 auto object1 = result[0];
 qDebug() << " a1 " << object1;
 @Then it prints: 
 a()
 ASSERT failure in QList<T>::operator[]: "index out of range",Which is normal if a() is empty O.o I'll have to inquire about what c++11 is, really thank you so much! Now I have new weekend reading :D 
- 
Hmm... what do you get if you do this? @ 
 qDebug() << myJson;
 qDebug() << QtJson::parse(myJson, ok);
 qDebug() << ok;
 @C++11 is the updated version of C++ which came out in 2011 :) It offers lots of new language features to make C++ more powerful and easier to use. C++14 is in the works, but it's no longer 2014 now so the update will probably be called C++15 instead. 
- 
This returns the next: @ 
 "{"data":"[{"Name":"One","Code":""},{"Name":"Two","Code":"Alpha"}]"}"QVariant(QVariantMap, QMap(("data", QVariant(QString, "[{"Name":"One","Code":""},{"Name":"Two","Code":"Alpha"}]") ) ) ) true 
 @wooow I thought there were only C, C# and C++ .... what an inonce girl I am XDDDD I will definitely look more about it at the weekend, it sounds really interesting! 
- 
[quote author="roseicollis" date="1423572240"] 
 @
 "{"data":"[{"Name":"One","Code":""},{"Name":"Two","Code":"Alpha"}]"}"
 @[/quote]I'm so sorry... I though myJson was 
 @
 [{"Name":"One","Code":""},{"Name":"Two","Code":"Alpha"}]
 @...that's why I thought your data was an array of 2 objects. :( Sorry for sending you on a wild goose chase! Anyway, your actual JSON data is: 1 object which contains 1 string value. I must say your data is formatted quite strangely (where did you get it from?). So, in the first run, you can only extract one string: 
 @
 QtJson::JsonObject outerObject = QtJson::parse(myJson, ok).toMap();
 QString innerString = outerObject.toString();qDebug() << myJson; 
 qDebug() << innerString;
 @You will see that myJson contains lots of '' characters, but innerString doesn't. That's because the data in outerObject is escaped -- the JSON parser treats it as a single string instead of a JSON array. Anyway, after parsing it the first time, you now have un-escaped data in innerString, so you can send it through the JSON parser again to extract the array: @ 
 QtJson::JsonArray outerArray = QtJson::parse(innerString, ok).toList();qDebug() << ok; 
 qDebug() << outerArray;
 @Now, you can apply my previous posts. Good luck! [quote author="roseicollis" date="1423572240"]wooow I thought there were only C, C# and C++ .... what an inonce girl I am XDDDD I will definitely look more about it at the weekend, it sounds really interesting![/quote]There are lots and lots of programming languages out there. :) C, C# and C++ are different languages. However, C++03, C++11, and C++14 are different versions of the same language. Happy reading! 
- 
[quote author="JKSH" date="1423574139"] 
 . :( Sorry for sending you on a wild goose chase!
 [/quote]
 No problem! I learnt a lot with that too :D[quote author="JKSH" date="1423574139"] 
 I must say your data is formatted quite strangely (where did you get it from?)
 [/quote]I don't know which should be its structure but this is what I will receive from a webservice which is made by a work mate and the only thing I know is: I have to parse it and show it on a widget (Still dunno if combobox or what will be the best option) [quote author="JKSH" date="1423574139"] 
 @
 QtJson::JsonObject outerObject = QtJson::parse(myJson, ok).toMap();
 QString innerString = outerObject.toString();qDebug() << myJson; 
 qDebug() << innerString;
 @
 [/quote]I had to make some changes to make it work: @ 
 QtJson::JsonObject outerObject = QtJson::parse(myJson, ok).toMap();
 QString innerString = outerObject["data"].toString();
 qDebug() << myJson;
 qDebug() << innerString;
 QtJson::JsonArray outerArray = QtJson::parse(innerString, ok).toList();
 qDebug() << ok;
 qDebug() << outerArray;
 auto object1 = outerArray[0].toMap();
 qDebug() << " DD" << object1["Name"];
 @So: - DD returns: DD QVariant(QString, "One")
 Now I'm trying to get that "One" string alone but at least I can see it!! I'm almost there, so cloose! [quote author="JKSH" date="1423574139"] 
 There are lots and lots of programming languages out there. :) C, C# and C++ are different languages.
 However, C++03, C++11, and C++14 are different versions of the same language.
 [/quote]Yes, I know there are soo many programming languages but didn't think about versions.. Never though they exist for the languages too haha 
