5

I am searching for a minimal full executable qt or c++ code example to parse and write this Json code:

{ "FirstName": "John", "LastName": "Doe", "MiddleName": null, "Age": 43, "Address": { "Street": "Downing Street 10", "City": "London", "Country": "Great Britain" }, "Phone numbers": [ "+44 1234567", "+44 2345678" ] "Valid":true, } 
  • The above example consists of an object with 5 key/value pairs. Two of the values are strings, one is a number,
  • one is another object and the last one an array.
  • A valid JSON document is either an array or an object, so a document always starts with a square or curly bracket.

EDIT:

  • Json has 2 more key/value pairs - value 'null' and 'bool'

And yes, I have seen a "Save Game Example" and tried to figure it out.

But after nearly a week I gave up to transfer a minimal Example without enums, QVectors and 3 different header Files over to my project to handle the code snippet. Doesn't matter if its for a widget or core code.

I already did a xml read and write program successfully but it seems I miss some Important point and get errors with json that may or may not have to do with the parsing. I am not able to rule it out without a minimal fully working code example.

So my question is: Could you please provide a minimal Example to write, read and print the Json file? Thanks upfront.

2 Answers 2

14

Since there does not seem to be a clear example on SO I wrote one. It uses simple mutation to create the objects, but if you have access to C++11 you should take a look at the std::initializer_list constructors, they make construction of objects much more compact.

#include <QJsonObject> #include <QJsonArray> #include <QJsonDocument> #include <QtGlobal> #include <QTextStream> #include <QDebug> int main() { // 1. Create the document QJsonObject root; root["FirstName"] = "John"; root["LastName"] = "Doe"; root["Age"] = 43; // Construct nested object first, then store it in `root` QJsonObject Address; Address["Street"] = "Downing Street 10"; Address["City"] = "London"; Address["Country"] = "Great Britain"; root["Address"] = Address; QJsonArray PhoneNumbers; PhoneNumbers.push_back("+44 1234567"); PhoneNumbers.push_back("+44 2345678"); root["Phone Numbers"] = PhoneNumbers; // `ba` contains JSON QByteArray ba = QJsonDocument(root).toJson(); QTextStream ts(stdout); ts << "rendered JSON" << endl; ts << ba; { QFile fout("test.json"); fout.open(QIODevice::WriteOnly); fout.write(ba); } // 2. Now read it back in QJsonParseError parseError; QJsonDocument doc2; { QFile fin("test.json"); fin.open(QIODevice::ReadOnly); QByteArray ba2 = fin.readAll(); doc2 = QJsonDocument::fromJson(ba2, &parseError); } if (parseError.error != QJsonParseError::NoError) { qWarning() << "Parse error at" << parseError.offset << ":" << parseError.errorString(); } else { ts << "parsed JSON" << endl; ts << doc2.toJson(QJsonDocument::Compact); //or QJsonDocument::Indented for a JsonFormat } } 
Sign up to request clarification or add additional context in comments.

2 Comments

Really nice, thanks for your fast response. That looks awsome! Just one thing, could you add a QFile writing to your example that creates a test.json file and reads it in? Just saw that I didn't explicitly mentioned it in the question, sry. I am trying to figure it out myself too tho since this example is really nice. Thanks so much upfront!
yeah, i finally got it figured out for me with your help and some books. Now I am able to finally store data in json format that should be faster as xml with big data. Still - Qt is really nice, some times it just needs a bit for me to understand the fundamentals
7

I guess it might help someone else too, I figured it all out, thanks to @Botje for his example, really helped. In general it is easy for me to remember to represent data as QByteArray in the memory.

A minimal example to access and also use every single value stored in a json file, you are welcome:

(Yes, I could have written it even more compact but I guess this makes it easier to understand, so I spared functions/classes/structs for the sake of readability.)

#include <QCoreApplication> #include <QString> #include <QVariant> #include <QFile> #include <QByteArray> #include <QTextStream> #include <QDebug> //json specific #include <QJsonParseError> #include <QJsonDocument> #include <QJsonArray> #include <QJsonObject> #include <QJsonParseError> #include <QJsonValue> void writeJsonFile(); void readJsonFile(); int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); writeJsonFile(); readJsonFile(); return a.exec(); } void writeJsonFile() { qDebug() << "Write Json File: "; //1. Create a QJsonObject and add values to it QJsonObject jsonObj; jsonObj["FirstName"] = "John"; //no value will be written as null in the json file jsonObj["MiddleName"]; jsonObj["LastName"] = "Doe"; jsonObj["Age"] = 43; //2. Create Item of Json Object content (object of object) QJsonObject jsonItemObj; jsonItemObj["Street"] = "Downing Street 10"; jsonItemObj["City"] = "London"; jsonItemObj["Country"] = "Great Britain"; //3. Add jsonItemObj to jsonObj and give it an object Name jsonObj["Address"] = jsonItemObj; //4. Create jsonArray and fill it with values - similar to filling a vector QJsonArray jsonArray; jsonArray.append("+44 1234567"); jsonArray.append("+44 2345678"); //Add a bool to the Object jsonObj["Valid"] = true; //5. Add jsonArray to jsonObj and give it an object Name jsonObj["Phone numbers"] = jsonArray; //(It can also be added to the jsonItemObj to be inline with the Address section) //with jsonItemObj["Phone numbers"] = jsonArray or as much objects of objects //you need /* As I understood it, most Qt classes use a QByteArray to handle data internally * because it is really fast/efficient, * also QFile QIODevice, it is a good idea to hold the read/write * QIODevice data as QByteArray in the Memory */ //6. Create a QByteArray and fill it with QJsonDocument (json formatted) QByteArray byteArray; byteArray = QJsonDocument(jsonObj).toJson(); //7. Open a QFile and write the byteArray filled with json formatted data //thanks to the QJsonDocument() Class to the file QFile file; file.setFileName("file.json"); if(!file.open(QIODevice::WriteOnly)){ qDebug() << "No write access for json file"; return; } //8. finally write the file and close it file.write(byteArray); file.close(); //9. Print out the byteArray to the terminal QTextStream textStream(stdout); textStream << "Rendered json byteArray text: " << endl; textStream << byteArray << endl; } void readJsonFile() { qDebug() << "Read Json File:"; //1. Open the QFile and write it to a byteArray and close the file QFile file; file.setFileName("file.json"); if(!file.open(QIODevice::ReadOnly)){ qDebug() << "Json filef couldn't be opened/found"; return; } QByteArray byteArray; byteArray = file.readAll(); file.close(); //2. Format the content of the byteArray as QJsonDocument //and check on parse Errors QJsonParseError parseError; QJsonDocument jsonDoc; jsonDoc = QJsonDocument::fromJson(byteArray, &parseError); if(parseError.error != QJsonParseError::NoError){ qWarning() << "Parse error at " << parseError.offset << ":" << parseError.errorString(); return; } //3. Create a jsonObject and fill it with the byteArray content, formatted //and holding by the jsonDocument Class QJsonObject jsonObj; jsonObj = jsonDoc.object(); //4. Now picking the jsonValues and printing them out or do what ever you need QJsonValue jsonVal; QTextStream textStream(stdout); jsonVal = jsonObj.value("FirstName"); textStream << jsonVal.toString() << endl; jsonVal = jsonObj.value("MiddleName"); //null gets back to an empty fild - added the sting "null/empty" to make it visible textStream << jsonVal.toVariant().toString() << "null/empty" << endl; jsonVal = jsonObj.value("LastName"); textStream << jsonVal.toString() << endl; //The number has to be converted to an int and than to a string to print it jsonVal = jsonObj.value("Age"); textStream << QString::number(jsonVal.toInt()) << endl; //5. Now we need to fill the object of the object. To do that, we need //the Item Object and a jsonSubVal object for json without a loop QJsonObject jsonItemObj; QJsonValue jsonSubVal; jsonVal = jsonObj.value(QString("Address")); jsonItemObj = jsonVal.toObject(); jsonSubVal = jsonItemObj["Street"]; textStream << jsonSubVal.toString() << endl; jsonSubVal = jsonItemObj["City"]; textStream << jsonSubVal.toString() << endl; jsonSubVal = jsonItemObj["Country"]; textStream << jsonSubVal.toString() << endl; //6. now the Phone Numbers array with a loop QJsonArray jsonArray; jsonArray = jsonObj["Phone numbers"].toArray(); for(int i = 0; i < jsonArray.size(); i++) textStream << jsonArray[i].toString() << endl; textStream << "or with foreach" << endl; foreach(QJsonValue v, jsonArray) textStream << v.toString() << endl; //7. And finally the bool value: jsonVal = jsonObj.value(QString("Valid")); textStream << jsonVal.toVariant().toString() << endl; textStream << "or as number, not a string: "; textStream << (QString::number(jsonVal.toInt())) << endl; textStream << "\nThe whole file as printed in the file \n" << jsonDoc.toJson(QJsonDocument::Indented); 

enter image description here

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.