Parsing JsonDocument the best way with Qt

I am new to Qt and I have a JSON document received from my home theater kodi and i want to parse it the best way. Can you help me with some code snippet?

Here is my JSON file

{
   "id":12345,
   "jsonrpc":"2.0",
   "result":{
      "item":{
         "fanart":"",
         "id":999,
         "label":"xyz",
         "thumbnail":"image:",
         "title":"xyz",
         "type":"channel"
      }
   }
}

Currently here is my code and it’s complicated:

QJsonDocument doc = QJsonDocument::fromJson(answer.toUtf8(), &parseerror);
map = doc.toVariant().toMap();
type = map.value("result").toMap().value("item").toMap().value("type")

Is there a better and faster way to access the type value?

Answer

When I need to serialize/deserialize a lot, I like to use the meta type system. I therefore wrote some lines to do this here: https://github.com/carlonluca/lqobjectserializer.

For your case, deserialization could be done by declaring each object as a QGadget or QObject first (this syntax comes from my other project, https://github.com/carlonluca/lqtutils, but it is not mandatory):

L_BEGIN_GADGET(KodiResponseItem)
L_RW_GPROP(QString, fanart, setFanart)
L_RW_GPROP(QString, label, setLabel)
L_RW_GPROP(int, id, setId)
L_RW_GPROP(QString, thumbnail, setThumbnail)
L_RW_GPROP(QString, title, setTitle)
L_RW_GPROP(QString, type, setType)
L_END_GADGET

L_BEGIN_GADGET(KodiResponseResult)
L_RW_GPROP(KodiResponseItem*, item, setItem, nullptr)
L_END_GADGET

L_BEGIN_GADGET(KodiResponse)
L_RW_GPROP(int, id, setId)
L_RW_GPROP(QString, jsonrpc, setJsonrpc)
L_RW_GPROP(KodiResponseResult*, result, setResult, nullptr)
L_END_GADGET

then register the meta type as Qt requires:

qRegisterMetaType<KodiResponseItem*>();
qRegisterMetaType<KodiResponseResult*>();
qRegisterMetaType<KodiResponse*>();
qRegisterMetaType<KodiResponseItem>();
qRegisterMetaType<KodiResponseResult>();
qRegisterMetaType<KodiResponse>();

then serialize or deserialize where you need to:

LDeserializer<KodiResponse> deserializer;
QScopedPointer<KodiResponse> m(deserializer.deserialize(jsonString));

QVERIFY(m);
QCOMPARE(m->id(), 12345);
QCOMPARE(m->result()->item()->type(), QSL("channel"));

// Remember to free gadget's manually. QObject's do not need this.
delete m->result()->item();
delete m->result();

This is my solution, but I remember other solutions ara available that does something similar.

Leave a Reply

Your email address will not be published. Required fields are marked *