Qt使用QJsonDocument、QJsonObject、QJsonArray解析JSON

Posted

技术标签:

【中文标题】Qt使用QJsonDocument、QJsonObject、QJsonArray解析JSON【英文标题】:Qt parsing JSON using QJsonDocument, QJsonObject, QJsonArray 【发布时间】:2013-11-06 20:32:30 【问题描述】:

我正在使用 Qt5。我正在尝试从 json 对象中获取值。这是我试图从中获取数据的 json 对象的样子:


    "success": true,
    "properties": [
        
            "ID": 1001,
            "PropertyName": "McDonalds",
            "key": "00112233445566778899aabbccddeeff"
        ,
        
            "ID": 1002,
            "PropertyName": "Burger King",
            "key": "10112233445566778899aabbccddeeff"
        ,
        
            "ID": 1003,
            "PropertyName": "Taco Bell",
            "key": "20112233445566778899aabbccddeeff"
        
    ]

如何在 Qt 中创建三个包含 properties[x].IDproperties[x].PropertyNameproperties[x].key 的数组?

编辑:

使用QScriptEngine我试过这个:

QString data = (QString)reply->readAll();

QScriptEngine engine;

QScriptValue result = engine.evaluate(data);

qDebug() << result.toString();

Debug 提示“SyntaxError: Parse error”

【问题讨论】:

其实我现在正在尝试使用 QScriptEngine。我现在正在看这个例子:makina-corpus.org/blog/access-json-webservice-qt-c 【参考方案1】:

我想通了:

QStringList propertyNames;
QStringList propertyKeys;
QString strReply = (QString)reply->readAll();
QJsonDocument jsonResponse = QJsonDocument::fromJson(strReply.toUtf8());
QJsonObject jsonObject = jsonResponse.object();
QJsonArray jsonArray = jsonObject["properties"].toArray();

foreach (const QJsonValue & value, jsonArray) 
    QJsonObject obj = value.toObject();
    propertyNames.append(obj["PropertyName"].toString());
    propertyKeys.append(obj["key"].toString());

【讨论】:

什么是reply-&gt;readAll(); 回复来自什么? HTTP 服务器回复?您通过 HTTP get/post 方法访问数据库?我只是好奇。 我有 networkReply Like this ["Serial Number":"0000000123","Trip Number":"0000000234","Destination":"blr","Passenger Name":"name", "Serial Number":"0000000125","Trip Number":"0000002314","Destination":"rtg","Passenger Name":"name3", "Serial Number":"0000000125","Trip Number":"0000002345","Destination":"udp","Passenger Name":"name2", "Serial Number":"0000000124","Trip Number":"0000009878","Destination":"drm","Passenger Name":"name1"] 如何使用你的答案解析这个? 嗯,不同之处在于你有一个数组,在我的示例中我从一个对象开始。我假设您可以先拨打QString strReply = (QString)reply-&gt;readAll();,然后拨打QJsonDocument jsonResponse = QJsonDocument::fromJson(strReply.toUtf8());,然后拨打QJsonArray jsonArray = jsonResponse.array();。免责声明:我实际上并没有尝试过,但我认为它会起作用。 这是非常低效的。当您将 readAll() 分配给 QString 时,您会导致字节数组从 utf8 字节转换为 utf16 QString。 then 当您调用 fromJson 时,您将导致 utf16 字符串转换回新的 utf8 字节数组。将 strReply 更改为 QByteArray 即可避免所有这些毫无意义的转换。更重要的是,如果您在内存受限的设备上运行此代码,您可以避免大约 4 倍的内存开销。【参考方案2】:

这是一个例子 How To Manipulate JSON With C++ and Qt.

// reads a json file from disk to QVariantMap
// originally from http://erickveil.github.io/2016/04/06/How-To-Manipulate-JSON-With-C++-and-Qt.html
bool readJsonFile(std::string file_path, QVariantMap& result)

    // step 1
    QFile file_obj(QString::fromStdString(file_path));
    if (!file_obj.open(QIODevice::ReadOnly)) 
    std::cout << "Failed to open " << file_path << std::endl;
    exit(1);
    

    // step 2
    QTextStream file_text(&file_obj);
    QString json_string;
    json_string = file_text.readAll();
    file_obj.close();
    QByteArray json_bytes = json_string.toLocal8Bit();

    // step 3
    auto json_doc = QJsonDocument::fromJson(json_bytes);

    if (json_doc.isNull()) 
        std::cout << "Failed to create JSON doc." << std::endl;
        return false;
    
    if (!json_doc.isObject()) 
        std::cout << "JSON is not an object." << std::endl;
        return false;
    

    QJsonObject json_obj = json_doc.object();

    if (json_obj.isEmpty()) 
        std::cout << "JSON object is empty." << std::endl;
        return false;
    

    // step 4
    result = json_obj.toVariantMap();
    return true;


// writes a QVariantMap to disk
bool writeJsonFile(QVariantMap point_map, std::string file_path)

    QJsonObject json_obj = QJsonObject::fromVariantMap(point_map);
    QJsonDocument json_doc(json_obj);
    QString json_string = json_doc.toJson();

    QFile save_file(QString::fromStdString(file_path));
    if (!save_file.open(QIODevice::WriteOnly)) 
        std::cout << "failed to open save file" << std::endl;
        return false;
    
    save_file.write(json_string.toLocal8Bit());
    save_file.close();
    return true;

【讨论】:

【参考方案3】:

我正在使用 QT 网络向 Firebase 发出 API 请求 但由于某种原因,我收到了一个充满数据的响应,但是在解析为数组时我收到了 null。

void firebaseHandler::parseResponse(const QString &response)
    @TODO for some reason sometimes the arrayData is empty 

    QJsonDocument jsonDocument = QJsonDocument::fromJson(response.toUtf8());
    QJsonValue kind =  jsonDocument.object().value("kind");
    QJsonArray arrayData = jsonDocument.array();

     qDebug() << "json response is " << jsonDocument.toJson();

【讨论】:

以上是关于Qt使用QJsonDocument、QJsonObject、QJsonArray解析JSON的主要内容,如果未能解决你的问题,请参考以下文章

Qt 和 JSON 资源解析 - 空 QJSONDocument

在Qt中使用QJsonDocument解析嵌套的JSON

使用非 Qt 从 Qt QJsonDocument::toBinaryData 读取二进制 Json?

QT学习_QT解析Json格式文件

如何将多个 QJsonObject 添加到 QJsonDocument - Qt

QJsonDocument实现Qt下JSON文档读写