2010-11-12 6 views
27

Potrzebuję parsować obiekt JSON przez Qt. Jaki jest najłatwiejszy/najszybszy sposób na zrobienie tego?Najprostszy sposób analizowania JSON w Qt 4.7

+0

See [Best parser JSON dla Qt? ] (http://stackoverflow.com/questions/1825892?tab=newest#tab-top). –

+0

Próbowałem, że to nie działa – wael34218

+3

Wygląda na to, że Qt5 ma kilka klas JSON. http://qt-project.org/doc/qt-5.0/qtcore/json.html –

Odpowiedz

15

Wypróbuj QJson.

QJson jest aktywnie rozwijany (i używany przez KDE, jeśli się nie mylę). Najlepiej jest sprawdzić kod źródłowy bezpośrednio i zbudować go samodzielnie. Nie ma zależności od QJson (z wyjątkiem Qt i CMake). Jest to dość proste w użyciu też spojrzeć na kilka przykładów wykorzystania:

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

7

Tutaj to koder/dekoder JTS w stylu Qt

#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; 
} 
+0

To wygląda bardzo ładnie ... ale nie kompiluje ... nieokreślonego odniesienia do QScriptEngine :: newObject ...... i dodałem #include w pliku json.h. Czy jest to możliwe nawet z QT 4.8.1. ? – user568021

+0

@ user568021 Kompiluje się dla mnie dobrze z Qt 4.8.2. –

+0

Niesamowite rozwiązanie! Byłaby to przyjemna biblioteka tylko dla nagłówków, wystarczy dołączyć i używać raczej całą bibliotekę kompilacji z nieskończonymi zależnościami. Coś, co przekształci tę QMap w obiekt, czyni ją doskonałą. Udało mi się to zrobić, zostawię tutaj kod, który będzie używany z twoim kodem. – Jack

5

Wiem, że ta odpowiedź jest spóźniona, ale ostatnio stworzyłem projekt pomóż stworzyć kod, który ma być skompilowany zarówno na Qt4, jak i Qt5, i zajmuje się JSON.

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

Ta biblioteka jest wcięty być spadek zamiennik QJsonDocument w Qt4 i użyje klas Qt, gdy używany w Qt5. Powinno to być dość płynne przejście. Nie jest w 100% kompletny, ale główne funkcje są tam :-).

+0

Świetna odpowiedź, którą przestawiłem. Tylko mały dodatek do twojego kodu w 'QJsonValue.h':' Q_DECLARE_METATYPE (QJsonValue) ', aby ta klasa była użyteczna w niektórych szczególnych przypadkach. – jonathanzh

+0

Pewnie, mogę dodać, że :-) –

18

JSON parsowania jest teraz obsługiwana w Qt 5. Oto jak załadować i analizować dokument:

#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(); 
+5

Pytanie dotyczy wersji 4.7 – dtech

+1

, dzięki temu pomogło mi to. – Goddard

0

Polecam qjson-backport, ponieważ używa tego samego API jak w Qt5.

Możesz warunkowo załadować bibliotekę, gdy używasz Qt4, i używać domyślnej implementacji podczas używania Qt5.

Mój plik qjson.pri wygląda następująco:

!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 

}