38

I'm using Qt5. I am trying to obtain values from a json object. Here is what the json object looks like that I am trying to get data from:

{
    "success": true,
    "properties": [
        {
            "ID": 1001,
            "PropertyName": "McDonalds",
            "key": "00112233445566778899aabbccddeeff"
        },
        {
            "ID": 1002,
            "PropertyName": "Burger King",
            "key": "10112233445566778899aabbccddeeff"
        },
        {
            "ID": 1003,
            "PropertyName": "Taco Bell",
            "key": "20112233445566778899aabbccddeeff"
        }
    ]
}

How can I create three arrays that contain properties[x].ID, properties[x].PropertyName, and properties[x].key in Qt?

Edit:

Using QScriptEngine I tried this:

QString data = (QString)reply->readAll();

QScriptEngine engine;

QScriptValue result = engine.evaluate(data);

qDebug() << result.toString();

Debug is saying "SyntaxError: Parse error"

1

3 Answers 3

79

I figured it out:

QStringList propertyNames;
QStringList propertyKeys;
QString strReply = (QString)reply->readAll();
QJsonDocument jsonResponse = QJsonDocument::fromJson(strReply.toUtf8());
QJsonObject jsonObject = jsonResponse.object();
QJsonArray jsonArray = jsonObject["properties"].toArray();

foreach (const QJsonValue & value, jsonArray) {
    QJsonObject obj = value.toObject();
    propertyNames.append(obj["PropertyName"].toString());
    propertyKeys.append(obj["key"].toString());
}
Sign up to request clarification or add additional context in comments.

4 Comments

What is reply->readAll(); Reply from what? HTTP server reply? You accessed database via HTTP get/post method? I'm just curious.
I have networkReply Like this [{"Serial Number":"0000000123","Trip Number":"0000000234","Destination":"blr","Passenger Name":"name"}, {"Serial Number":"0000000125","Trip Number":"0000002314","Destination":"rtg","Passenger Name":"name3"}, {"Serial Number":"0000000125","Trip Number":"0000002345","Destination":"udp","Passenger Name":"name2"}, {"Serial Number":"0000000124","Trip Number":"0000009878","Destination":"drm","Passenger Name":"name1"}] How can I parse this using your answer?
Well the difference there is that you have an array where I started with an object in my example. I would assume that you could call QString strReply = (QString)reply->readAll(); then QJsonDocument jsonResponse = QJsonDocument::fromJson(strReply.toUtf8()); then QJsonArray jsonArray = jsonResponse.array();. Disclaimer: I didn't actually try this, but I would think it would work.
This is extremely inefficient. When you assign readAll() to a QString you're causing a byte array to be converted from utf8 bytes to a utf16 QString. And then when you call fromJson you're causing the utf16 string to be converted back into a new utf8 byte array. Change strReply to a QByteArray and you avoid all this pointless conversion. More to the point, if you're running this code on a memory constrained device you avoid about 4x the memory overhead.
6

Here is an example from How To Manipulate JSON With C++ and Qt.

// reads a json file from disk to QVariantMap
// originally from http://erickveil.github.io/2016/04/06/How-To-Manipulate-JSON-With-C++-and-Qt.html
bool readJsonFile(std::string file_path, QVariantMap& result)
{
    // step 1
    QFile file_obj(QString::fromStdString(file_path));
    if (!file_obj.open(QIODevice::ReadOnly)) {
    std::cout << "Failed to open " << file_path << std::endl;
    exit(1);
    }

    // step 2
    QTextStream file_text(&file_obj);
    QString json_string;
    json_string = file_text.readAll();
    file_obj.close();
    QByteArray json_bytes = json_string.toLocal8Bit();

    // step 3
    auto json_doc = QJsonDocument::fromJson(json_bytes);

    if (json_doc.isNull()) {
        std::cout << "Failed to create JSON doc." << std::endl;
        return false;
    }
    if (!json_doc.isObject()) {
        std::cout << "JSON is not an object." << std::endl;
        return false;
    }

    QJsonObject json_obj = json_doc.object();

    if (json_obj.isEmpty()) {
        std::cout << "JSON object is empty." << std::endl;
        return false;
    }

    // step 4
    result = json_obj.toVariantMap();
    return true;
}

// writes a QVariantMap to disk
bool writeJsonFile(QVariantMap point_map, std::string file_path)
{
    QJsonObject json_obj = QJsonObject::fromVariantMap(point_map);
    QJsonDocument json_doc(json_obj);
    QString json_string = json_doc.toJson();

    QFile save_file(QString::fromStdString(file_path));
    if (!save_file.open(QIODevice::WriteOnly)) {
        std::cout << "failed to open save file" << std::endl;
        return false;
    }
    save_file.write(json_string.toLocal8Bit());
    save_file.close();
    return true;
}

Comments

0

I'm using QT Network for my API request to Firebase but for some reason, I received a response full of data but when parsing to an array I received null.

void firebaseHandler::parseResponse(const QString &response){
    @TODO for some reason sometimes the arrayData is empty 

    QJsonDocument jsonDocument = QJsonDocument::fromJson(response.toUtf8());
    QJsonValue kind =  jsonDocument.object().value("kind");
    QJsonArray arrayData = jsonDocument.array();

     qDebug() << "json response is " << jsonDocument.toJson();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.