[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