33

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

3

6 Answers 6

18

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/

Sign up to request clarification or add additional context in comments.

Comments

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(); 

1 Comment

The question is about version 4.7
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

1 Comment

Linkrot. From some random "info" domain. Thanks for nothing.
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; } 

3 Comments

This looks very nice... but does not compile... undefined reference to QScriptEngine::newObject ...... and I added #include <QtScript/qscriptengine.h> in the json.h file. Is it even possible to use this with QT 4.8.1. ?
@user568021 It compiles just fine for me with Qt 4.8.2.
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.
7

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

2 Comments

Great answer which I have upvoted. Just a small addition to your code in QJsonValue.h: Q_DECLARE_METATYPE(QJsonValue) to make this class usable in some special cases.
Sure, I can add that :-)
5

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 } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.