sainimu78
sainimu78

Reputation: 63

Is there a way find a key in the whole json file using QJsonObject?

A key in any level of the json hierarchy, how can I find that key without knowing exact keys in the path?

Upvotes: 1

Views: 1760

Answers (1)

TrebledJ
TrebledJ

Reputation: 8997

Generally, this can be solved with a recursive function (a function which calls itself). We first pass it the document's object, then check the object's keys. If no keys are found, we will apply the same function on the values of each key. If an array is passed, we should iterate through it.

QJsonValue findKey(const QString& key, const QJsonValue& value) {
    if (value.isObject()) {
        const QJsonObject obj = value.toObject();
        if (obj.contains(key))
            return obj.value(key);           // return 'early' if object contains key    

        for (const auto& value : obj) {
            QJsonValue recurse = findKey(key, value);  // call itself, forwarding a value        
            if (!recurse.isNull())
                return recurse;              // value found, return 'early'
        }
    } else if (value.isArray()) {
        for (const auto& value : value.toArray()) {
            QJsonValue recurse = findKey(key, value);
            if (!recurse.isNull())
                return recurse;
        }
    }

    return QJsonValue();          // base case: a null value
}

int main(int argc, char *argv[])
{
    QFile file(":/res/scratch.json");   // json stored in a qrc with /res/ prefix
    file.open(QIODevice::ReadOnly);

    if (!file.isOpen()) {
        qDebug() << "error: couldn't open scratch.json";
        return 0;
    }

    QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
    qDebug() << "value:" << findKey("treasure", doc.object());
}

An example of a JSON file and relevant output:

scratch.json:

{
    "deck": [
        "first mate",
        "sailor",
        "john muir"
    ],
    "cabin": [
        {
            "name": "lamp"
        },
        {
            "name": "treasure chest",
            "items": {
                "diamonds": 3,
                "silver": 5,
                "gold": 10,
                "safebox": {
                    "treasure": "shiny"
                }
            }
        }
    ]
}

Output:

value: QJsonValue(string, "shiny")

Upvotes: 4

Related Questions