Question

I need to parse JSON object through Qt. What is the easiest/fastest way to do it?

Was it helpful?

Solution

Try QJson.

QJson is actively developed (and used by KDE, if I'm not mistaken). The best is to checkout the source code directly and built it yourself. There is no dependencies to QJson (except for Qt and CMake). It's pretty simple to use too, have a look at some usage examples :

http://qjson.sourceforge.net/usage/

OTHER TIPS

JSON parsing is now supported in Qt 5. Here's how to load and parse a document:

#include <QByteArray>
#include <QFile>
#include <QJsonObject>
#include <QJsonDocument>

// ...

// Read JSON file
QFile file("/path/to/file.json");
file.open(QIODevice::ReadOnly);
QByteArray rawData = file.readAll();

// Parse document
QJsonDocument doc(QJsonDocument::fromJson(rawData));

// Get JSON object
QJsonObject json = doc.object();

// Access properties
qDebug() << json["something"].toString();

If you don't want to depend on external libraries you could use the QScriptEngine

http://qtwiki.remdex.info/Parsing_JSON_with_QT_using_standard_QT_library

Here is Qt style json encoder/decoder

#include "json.h"

#include <QScriptEngine>
#include <QScriptValueIterator>

Json::Json()
{
}


QString Json::encode(const QMap<QString,QVariant> &map)
{
    QScriptEngine engine;
    engine.evaluate("function toString() { return JSON.stringify(this) }");

    QScriptValue toString = engine.globalObject().property("toString");
    QScriptValue obj = encodeInner(map, &engine);
    return toString.call(obj).toString();

}

QMap<QString, QVariant> Json::decode(const QString &jsonStr)
{
    QScriptValue object;
    QScriptEngine engine;
    object = engine.evaluate("(" + jsonStr + ")");
    return decodeInner(object);
}

QScriptValue Json::encodeInner(const QMap<QString,QVariant> &map, QScriptEngine* engine)
{
    QScriptValue obj = engine->newObject();
    QMapIterator<QString, QVariant> i(map);
    while (i.hasNext()) {
        i.next();
        if (i.value().type() == QVariant::String)
            obj.setProperty(i.key(), i.value().toString());
        else if (i.value().type() == QVariant::Int)
            obj.setProperty(i.key(), i.value().toInt());
        else if (i.value().type() == QVariant::Double)
            obj.setProperty(i.key(), i.value().toDouble());
        else if (i.value().type() == QVariant::List)
            obj.setProperty(i.key(), qScriptValueFromSequence(engine, i.value().toList()));
        else if (i.value().type() == QVariant::Map)
            obj.setProperty(i.key(), encodeInner(i.value().toMap(), engine));
    }
    return obj;
}


QMap<QString, QVariant> Json::decodeInner(QScriptValue object)
{
    QMap<QString, QVariant> map;
    QScriptValueIterator it(object);
    while (it.hasNext()) {
        it.next();
        if (it.value().isArray())
            map.insert(it.name(),QVariant(decodeInnerToList(it.value())));
        else if (it.value().isNumber())
            map.insert(it.name(),QVariant(it.value().toNumber()));
        else if (it.value().isString())
            map.insert(it.name(),QVariant(it.value().toString()));
        else if (it.value().isNull())
            map.insert(it.name(),QVariant());
        else if(it.value().isObject())
            map.insert(it.name(),QVariant(decodeInner(it.value())));
    }
    return map;
}

QList<QVariant> Json::decodeInnerToList(QScriptValue arrayValue)
{
    QList<QVariant> list;
    QScriptValueIterator it(arrayValue);
    while (it.hasNext()) {
        it.next();
        if (it.name() == "length")
            continue;

        if (it.value().isArray())
            list.append(QVariant(decodeInnerToList(it.value())));
        else if (it.value().isNumber())
            list.append(QVariant(it.value().toNumber()));
        else if (it.value().isString())
            list.append(QVariant(it.value().toString()));
        else if (it.value().isNull())
            list.append(QVariant());
        else if(it.value().isObject())
            list.append(QVariant(decodeInner(it.value())));
    }
    return list;
}

I know this answer is late, but I recently created a project to help create code which is meant to compile on both Qt4 and Qt5 and deals with JSON.

https://code.google.com/p/qjson4/

This library is indented to be a drop in replacement for QJsonDocument in Qt4 and will use Qt's classes when used in Qt5. So it should be a fairly smooth transition. It's not 100% complete, but the major features are in there :-).

I would recommend qjson-backport, as it uses the same API as in Qt5.

You can conditionally load the library when you use Qt4, and use the default implementation when using Qt5.

My qjson.pri file looks like:

!greaterThan(QT_MAJOR_VERSION, 4): {

    INCLUDEPATH += \
        $$PWD

    SOURCES += \
        $$PWD/qjson.cpp \
        $$PWD/qjsonarray.cpp \
        $$PWD/qjsondocument.cpp \
        $$PWD/qjsonobject.cpp \
        $$PWD/qjsonparser.cpp \
        $$PWD/qjsonvalue.cpp \
        $$PWD/qjsonwriter.cpp

    HEADERS += \
        $$PWD/qjson_p.h \
        $$PWD/qjsonarray.h \
        $$PWD/qjsondocument.h \
        $$PWD/qjsonobject.h \
        $$PWD/qjsonparser_p.h \
        $$PWD/qjsonvalue.h \
        $$PWD/qjsonwriter_p.h

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top