Get nested json values
-
@avmg
If you do that, your emptyQJsonObject json
won't even have aFood
sub-object in it. You need to put stuff into your object.Untested, but you will want something like:
QJsonObject json, food, fruits; json["Food"] = food; food["Fruits"] = fruits; fruits["Apples"] = 10;
EDIT Wrong, see my next post for correction.
@JonB and is it possible to nest again?
The target of all of this is to save the values from a numeric struct into a json file, and show it in a treeview, I like the way how the json is organized because when you load it into the treeview it results very clean and organized for the user. Actually I can load the json and update the struct with its values, but when I modify the struct and I want to save it back into the json file is when I struggle... that's why i'm asking how to modify one specific value from a nested json, the json already exists, but I can't find the way to change it.
-
@JonB and is it possible to nest again?
The target of all of this is to save the values from a numeric struct into a json file, and show it in a treeview, I like the way how the json is organized because when you load it into the treeview it results very clean and organized for the user. Actually I can load the json and update the struct with its values, but when I modify the struct and I want to save it back into the json file is when I struggle... that's why i'm asking how to modify one specific value from a nested json, the json already exists, but I can't find the way to change it.
@avmg
I'm sorry, I don't have time right now to complete looking into this.I can say that my example for setting the values needs the order of its assignments reversed:
QJsonObject json, food, fruits; fruits["Apples"] = 10; food["Fruits"] = fruits; json["Food"] = food; // next line works right qDebug() << json["Food"].toObject()["Fruits"].toObject()["Apples"]; // assignment not right here, it must be into into a copy of objects json["Food"].toObject()["Fruits"].toObject()["Apples"] = 999; // next line wrong, still prints `10` qDebug() << json["Food"].toObject()["Fruits"].toObject()["Apples"];
Somewhere the assignment at the end needs to use
QJsonValueRef
s instead of thosetoObject()s
which I think are doing a copy. I may have time to look at it later, but have a play.... -
Hi JonB,
That's exactly what I was trying and the point where I got stacked, there's no error but the value isn't assigned... thanks anyway!
@avmg
I too have had little joy. In the end I searched, and you should read through (all of) https://stackoverflow.com/questions/17034336/how-to-change-qjsonobject-value-in-a-qjson-hierarchy-without-using-copies carefully.The gist being, you can't do it :)
According to information from Qt developer who actually wrote QJson in Qt5 -
What's currently included in Qt is a 'read-only' implementation to provide parsing facilities. He has an intention to extend design with 'references' support in future, but it's not yet done.
After wasting three hours of my life I can confirm that as of today this is still impossible with Qt 5.4. You can modify JSON objects, but not nested JSON objects.
You can pursue any of the suggestions there to achieve what you want.
Alternatively, which I would be tempted to do: convert the whole of the JSON object hierarchy into actual C++ structures/
QVariantList
s/whatever. Do your updates/manipulations on that, as C++/Qt variables instead of on the JSON object tree. And then regenerate the whole JSON document tree from your C++ structures and write that back to file. -
@avmg
I too have had little joy. In the end I searched, and you should read through (all of) https://stackoverflow.com/questions/17034336/how-to-change-qjsonobject-value-in-a-qjson-hierarchy-without-using-copies carefully.The gist being, you can't do it :)
According to information from Qt developer who actually wrote QJson in Qt5 -
What's currently included in Qt is a 'read-only' implementation to provide parsing facilities. He has an intention to extend design with 'references' support in future, but it's not yet done.
After wasting three hours of my life I can confirm that as of today this is still impossible with Qt 5.4. You can modify JSON objects, but not nested JSON objects.
You can pursue any of the suggestions there to achieve what you want.
Alternatively, which I would be tempted to do: convert the whole of the JSON object hierarchy into actual C++ structures/
QVariantList
s/whatever. Do your updates/manipulations on that, as C++/Qt variables instead of on the JSON object tree. And then regenerate the whole JSON document tree from your C++ structures and write that back to file. -
@JonB
Ok, so in the same way I'm actually loading the json into the treeview, I should make modifications there and do the opposite operation saving the treeview data into a json file, right?Thanks for your time!
@avmg
Yes, exactly that. You produced the treeview internally and output that as JSON. Now, read in the JSON , convert to treeview/internal format, do adds/deletes/updates where you know what you're doing in C++, finally ask for the tree to once again produce the whole of the JSON to save back externally. -
Hi again!
I'm trying to do what we were talking about but I'm fighting with the same thing but opposite...
How can I nest a value inside another in a json? I've tried things like:
json["Food"].toObject()["Fruits"].toObject()["Apples"].toDouble(5);
and
json["Food"].toObject()["Fruits"].toObject()["Apples"] = 5;
It doesn't generate errors but the file shows equal to null after Food... I imagine that firstly I should create another QJsonObject and insert it in another, but I've tried many things without success...
Any suggestion?
Thanks in advance! -
JonB already showed you how to do it: https://forum.qt.io/topic/116865/get-nested-json-values/13
-
JonB already showed you how to do it: https://forum.qt.io/topic/116865/get-nested-json-values/13
@Christian-Ehrlicher Hi Christian,
You are right, I was looking the line:
json["Food"].toObject()["Fruits"].toObject()["Apples"] = 999;
...but the solution was at the beginning just in front of me:
QJsonObject json, food, fruits; fruits["Apples"] = 10; food["Fruits"] = fruits; json["Food"] = food; // next line works right qDebug() << json["Food"].toObject()["Fruits"].toObject()["Apples"];
Thanks again and sorry, I didn't pay attention.
Cheers
-
@Christian-Ehrlicher Hi Christian,
You are right, I was looking the line:
json["Food"].toObject()["Fruits"].toObject()["Apples"] = 999;
...but the solution was at the beginning just in front of me:
QJsonObject json, food, fruits; fruits["Apples"] = 10; food["Fruits"] = fruits; json["Food"] = food; // next line works right qDebug() << json["Food"].toObject()["Fruits"].toObject()["Apples"];
Thanks again and sorry, I didn't pay attention.
Cheers
@avmg
Yes.Note that we are saying you can read nested JSON objects via
qDebug() << json["Food"].toObject()["Fruits"].toObject()["Apples"];
but you cannot write the value of a nested object via
json["Food"].toObject()["Fruits"].toObject()["Apples"] = 10;
That's just how it is, as the code above copies the JSON objects, so assigning does not change what is in
json[]...
. If you want to achieve the second example you have to build it up bit by bit as per the 4 linesQJsonObject json, food, fruits; fruits["Apples"] = 10; food["Fruits"] = fruits; json["Food"] = food;