2010-11-12 67 views
27

我需要通過Qt解析JSON對象。什麼是最簡單/最快捷的方法?在Qt 4.7中解析JSON的最簡單方法

+0

參見[最佳JSON解析器的Qt? ](http://stackoverflow.com/questions/1825892?tab=newest#tab-top)。 – 2010-11-12 23:44:48

+0

我試過了,它沒有工作 – wael34218 2010-11-12 23:48:53

+3

看起來像Qt5有一些JSON類。 http://qt-project.org/doc/qt-5.0/qtcore/json.html – 2013-11-05 17:30:28

回答

15

嘗試QJson。 012JJson是積極開發的(如果我沒有弄錯的話,KDE會使用它)。最好是直接簽出源代碼並自己構建它。 QJson沒有依賴關係(Qt和CMake除外)。這是非常簡單的使用也有看一些用法示例:

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

7

這裏是Qt風格json編碼器/解碼器

#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

這看起來很不錯...但不編譯...對QScriptEngine :: newObject的未定義引用......並且我在json.h文件中添加了#include 。是否有可能在QT 4.8.1中使用它。 ? – user568021 2013-12-16 19:51:28

+0

@ user568021它在Qt 4.8.2中編譯得很好。 – 2013-12-30 23:52:51

+0

真棒解決方案!這將是一個很好的僅包含頭文件的庫,只是包含和使用所有構建庫的所有東西都具有無限的依賴關係。把這個QMap轉換成一個對象會使它變得完美。我設法做到了,我將這裏的代碼留給代碼使用。 – Jack 2017-09-12 03:24:47

5

我知道這個答案很晚,但我最近創建了一個項目幫助創建代碼,以便在Qt4和Qt5上編譯並處理JSON。

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

這個庫縮進是在替代在Qt4的QJsonDocument下降和QT5使用時將使用Qt的類。所以它應該是一個相當平穩的過渡。它不是100%完整的,但主要功能在那裏:-)。

+0

我已經提出了很好的答案。在'QJsonValue.h'中添加一個小代碼:'Q_DECLARE_METATYPE(QJsonValue)',使這個類在一些特殊情況下可用。 – jonathanzh 2016-03-25 16:12:07

+0

當然,我可以補充說:-) – 2016-03-25 17:19:15

18

JSON解析現在支持的Qt 5以下是如何加載和分析文檔:

#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

問題是關於版本4.7 – dtech 2014-05-23 22:02:03

+1

謝謝這幫了我。 – Goddard 2015-02-19 00:22:34

0

我會建議qjson-backport,因爲它使用相同的API在QT5。

您可以在使用Qt4時有條件地加載庫,並在使用Qt5時使用默認實現。

qjson.pri文件看起來像:

!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 

}