33

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

laurent
  • 88,262
  • 77
  • 290
  • 428
wael34218
  • 4,860
  • 8
  • 44
  • 62

6 Answers6

18

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();
laurent
  • 88,262
  • 77
  • 290
  • 428
17

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/

Joshua D. Boyd
  • 4,808
  • 3
  • 29
  • 44
Symbiosoft
  • 4,681
  • 6
  • 32
  • 46
9

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;
}
user2243820
  • 91
  • 1
  • 1
  • This looks very nice... but does not compile... undefined reference to QScriptEngine::newObject ...... and I added #include in the json.h file. Is it even possible to use this with QT 4.8.1. ? – user568021 Dec 16 '13 at 19:51
  • @user568021 It compiles just fine for me with Qt 4.8.2. – Vern Jensen Dec 30 '13 at 23:52
  • Awesome solution! It would be a nice header-only library, just include-and-use rather all the all build library thing with infinite dependences. Something to turn that QMap into an object would make it perfect. I managed to do that I'll leave the code here to be used with your code. – Jack Sep 12 '17 at 03:24
9

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

Morten Kristensen
  • 7,412
  • 4
  • 32
  • 52
guruz
  • 1,604
  • 14
  • 21
6

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 :-).

Evan Teran
  • 87,561
  • 32
  • 179
  • 238
4

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

}
AntonyG
  • 861
  • 9
  • 22