Минимальный пример того, как читать, писать и печатать код Q Json (с QJsonDocument, QJsonArray, QJsonObject, QFile) - PullRequest
0 голосов
/ 07 апреля 2020

Я ищу минимальный полный исполняемый пример кода на qt или c ++ для анализа и записи этого Json кода:

{
    "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,
}
  • Приведенный выше пример состоит из объекта с ключом / значением 5 пар. Два значения являются строками, одно - число,
  • одно - другой объект, а последнее - массив.
  • Допустимый документ JSON является либо массивом, либо объектом, поэтому документ всегда начинается с квадратной или фигурной скобки.

РЕДАКТИРОВАТЬ:

  • Json имеет еще 2 пары ключ / значение - значение ' null 'и' bool '

И да, я видел "Пример сохранения игры" и пытался выяснить это.

Но спустя почти неделю я отказался от передачи минимального примера без перечислений, QVectors и 3 разных заголовочных файлов в мой проект для обработки фрагмента кода. Не имеет значения, для виджета или основного кода.

Я уже успешно выполнил xml программу для чтения и записи, но, похоже, я упустил важный момент и получил ошибки с json, которые могут или могут быть не надо делать с разбором. Я не могу исключить это без минимального полностью работающего примера кода.

Итак, мой вопрос: Не могли бы вы предоставить минимальный Пример для записи, чтения и печати файла Json? Спасибо заранее.

Ответы [ 2 ]

1 голос
/ 07 апреля 2020

Так как, кажется, нет четкого примера на SO, я написал один. Он использует простую мутацию для создания объектов, но если у вас есть доступ к C ++ 11, вы должны взглянуть на конструкторы std::initializer_list, они делают конструкцию объектов намного более компактной.

#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
    }
}
0 голосов
/ 18 апреля 2020

Полагаю, это может помочь и кому-то еще, я все понял, спасибо @Botje за его пример, который действительно помог. В общем, мне легко запомнить представление данных как QByteArray в памяти.

Минимальный пример для доступа, а также для использования каждого отдельного значения, хранящегося в файле json, вы можете:

(Да, я мог бы написать это еще более компактно, но, думаю, это облегчает понимание, поэтому я позаботился о функциях / классах / структурах ради удобства чтения.)

#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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...