简述Qt5中对JSON的生成与解析,你了解多少?

Qt5 包含用于处理 JSON 的类,全部以 QJson 开头(例如:,,)。 模块中,无需引入其他模块。

常用的 JSON 库

介绍JSON在各种语言中的应用。 C/C++中比较常用的JSON库主要有以下几个:

关于Qt中JSON的生成和解析,Qt5之前的版本可以使用QJson库,使用前需要单独下载并编译。 Qt5 提供了专门的相关类来读取和写入 JSON 文档。

JSON公共类

用于读取和写入 JSON 文档的类。

JSON 文档可以使用 ::() 从基于文本的表示形式转换,并使用 () 转换回文本。 该解析器非常快速且高效,并将 JSON 转换为 Qt 使用的二进制表示形式。

可以使用 !() 查询已解析文档的有效性。

如果要查询JSON文档是否包含数组或对象,请使用()和()。 可以使用 array() 或 () 检索文档中包含的数组或对象,然后读取或操作。

您还可以使用 () 或 () 从存储的二进制表示形式创建 JSON 文档。

该类封装了一个 JSON 数组。

JSON 数组是值的列表。 可以通过在数组中插入和删除来操作列表。

一种可以转换为一种,一种可以转换为另一种。 您可以使用 size() 查询条目数,使用 () 在指定索引处插入值,使用 () 删除指定索引处的值。

该类封装了一个 JSON 对象。

JSON 对象是“键/值对”的列表,其中键是唯一的字符串,值由 a 表示。

一种可以转换为一种,一种可以转换为另一种。 可以使用size()查询“键/值对”的数量,通过()插入“键/值对”,通过()删除指定的键。

一个类封装了一个值。

JSON 中的值有 6 种基本数据类型:

值可以由上述任何数据类型表示。 另外,还有一个特殊的标志来表示未定义的值,可以使用 () 进行查询。

可以通过type()或者()、()等访问函数来查询值的类型。 同样,可以通过()、()等函数将值转换为对应的存储类型。

用于报告 JSON 解析错误的类。

枚举:::

此枚举描述了解析 JSON 文档期间发生的错误类型。

常数值说明

::

没有发生错误

::

对象错误地以右花括号终止

::

缺少分隔不同项目的逗号

::

数组错误地以右括号终止

::r

对象中分隔键/值的冒号丢失

::

值非法

::

解析数字时,输入流结束

::

数字格式不正确

::e

输入时发生非法转义序列

::

输入时出现非法 UTF8 序列

::

10

字符串不以引号结尾

::

11

需要一个对象,但找不到

::

12

JSON 文档对于解析器来说嵌套太深

::

13

JSON 文档对于解析器来说太大

::

14

解析的文档末尾包含额外的乱码

简单的 JSON 对象

构造一个简单的 JSON 对象:

{
    "Cross Platform": true,
    "From": 1991,
    "Name": "Qt"
}

生成过程比较简单。 既然它是一个对象,那么你只需要使用它即可。

// 构建 JSON 对象
QJsonObject json;
json.insert("Name", "Qt");
json.insert("From", 1991);
json.insert("Cross Platform", true);
// 构建 JSON 文档
QJsonDocument document;
document.setObject(json);
QByteArray byteArray = document.toJson(QJsonDocument::Compact);
QString strJson(byteArray);
qDebug() << strJson;

分析如下:

QJsonParseError jsonError;
QJsonDocument doucment = QJsonDocument::fromJson(byteArray, &jsonError);  // 转化为 JSON 文档
if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) {  // 解析未发生错误
    if (doucment.isObject()) { // JSON 文档为对象
        QJsonObject object = doucment.object();  // 转化为对象
        if (object.contains("Name")) {  // 包含指定的 key
            QJsonValue value = object.value("Name");  // 获取指定 key 对应的 value
            if (value.isString()) {  // 判断 value 是否为字符串
                QString strName = value.toString();  // 将 value 转化为字符串
                qDebug() << "Name : " << strName;
            }
        }
        if (object.contains("From")) {
            QJsonValue value = object.value("From");
            if (value.isDouble()) {
                int nFrom = value.toVariant().toInt();
                qDebug() << "From : " << nFrom;
            }
        }
        if (object.contains("Cross Platform")) {
            QJsonValue value = object.value("Cross Platform");
            if (value.isBool()) {
                bool bCrossPlatform = value.toBool();
                qDebug() << "CrossPlatform : " << bCrossPlatform;
            }
        }
    }
}

注意:转换为 后,首先需要根据 的值判断转换是否成功,然后进行相应的转换分析。

简单的 JSON 数组

构造一个简单的 JSON 对象:

[
    "Qt",
    5.7,
    true
]

生成比较简单,既然是数组,只需要使用即可。

// 构建 JSON 数组
QJsonArray json;
json.append("Qt");
json.append(5.7);
json.append(true);
// 构建 JSON 文档
QJsonDocument document;
document.setArray(json);
QByteArray byteArray = document.toJson(QJsonDocument::Compact);
QString strJson(byteArray);
qDebug() << strJson;

需要注意的是,与上面不同的是,这里使用了()函数,因为它是一个数组!

分析如下:

QJsonParseError jsonError;
QJsonDocument doucment = QJsonDocument::fromJson(byteArray, &jsonError);  // 转化为 JSON 文档
if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) { // 解析未发生错误
    if (doucment.isArray()) { // JSON 文档为数组
        QJsonArray array = doucment.array();  // 转化为数组
        int nSize = array.size();  // 获取数组大小
        for (int i = 0; i < nSize; ++i) {  // 遍历数组
            QJsonValue value = array.at(i);
            if (value.type() == QJsonValue::String) {
                QString strName = value.toString();
                qDebug() << strName;
            }
            if (value.type() == QJsonValue::Double) {
                double dVersion = value.toDouble();
                qDebug() << dVersion;
            }
            if (value.type() == QJsonValue::Bool) {
                bool bCrossPlatform  = value.toBool();
                qDebug() << bCrossPlatform;
            }
        }
    }
}

与JSON对象类似,在遍历数组时,要获取每个值,首先需要确定值的类型(类似于is***()函数,这里是根据类型返回的枚举值来确定() 函数),然后进行相应的转换。

复杂的 JSON

构造一个复杂的 JSON 对象:

{
    "Company": "Digia",
    "From": 1991,
    "Name": "Qt",
    "Page": {
        "Developers": "https://www.qt.io/developers/",
        "Download": "https://www.qt.io/download/",
        "Home": "https://www.qt.io/"
    },
    "Version": [
        4.8,
        5.2,
        5.7
    ]
}

包含一个具有五个“键/值对”的对象,其中两个 (,Name) 是字符串,一个 (From) 是数字,一个 (Page) 是对象,一个 () 是数组。

要生成如此复杂的 JSON 文档,您需要分别构造对象和数组,然后将它们连接起来:

// 构建 Json 数组 - Version
QJsonArray versionArray;
versionArray.append(4.8);
versionArray.append(5.2);
versionArray.append(5.7);
// 构建 Json 对象 - Page
QJsonObject pageObject;
pageObject.insert("Home", "https://www.qt.io/");
pageObject.insert("Download", "https://www.qt.io/download/");
pageObject.insert("Developers", "https://www.qt.io/developers/");
// 构建 Json 对象
QJsonObject json;
json.insert("Name", "Qt");
json.insert("Company", "Digia");
json.insert("From", 1991);
json.insert("Version", QJsonValue(versionArray));
json.insert("Page", QJsonValue(pageObject));
// 构建 Json 文档
QJsonDocument document;
document.setObject(json);
QByteArray byteArray = document.toJson(QJsonDocument::Compact);
QString strJson(byteArray);
qDebug() << strJson;

解析部分实际上并不像看起来那么复杂。 你只需要一步步了解对应的类型,然后进行对应的转换即可。

QJsonParseError jsonError;
QJsonDocument doucment = QJsonDocument::fromJson(byteArray, &jsonError);  // 转化为 JSON 文档
if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) {  // 解析未发生错误
    if (doucment.isObject()) {  // JSON 文档为对象
        QJsonObject object = doucment.object();  // 转化为对象
        if (object.contains("Name")) {
            QJsonValue value = object.value("Name");
            if (value.isString()) {
                QString strName = value.toString();
                qDebug() << "Name : " << strName;
            }
        }
        if (object.contains("Company")) {
            QJsonValue value = object.value("Company");
            if (value.isString()) {
                QString strCompany = value.toString();
                qDebug() << "Company : " << strCompany;
            }
        }
        if (object.contains("From")) {
            QJsonValue value = object.value("From");
            if (value.isDouble()) {
                int nFrom = value.toVariant().toInt();
                qDebug() << "From : " << nFrom;
            }
        }
        if (object.contains("Version")) {
            QJsonValue value = object.value("Version");
            if (value.isArray()) {  // Version 的 value 是数组
                QJsonArray array = value.toArray();
                int nSize = array.size();
                for (int i = 0; i < nSize; ++i) {
                    QJsonValue value = array.at(i);
                    if (value.isDouble()) {
                        double dVersion = value.toDouble();
                        qDebug() << "Version : " << dVersion;
                    }
                }
            }
        }
        if (object.contains("Page")) {
            QJsonValue value = object.value("Page");
            if (value.isObject()) {  // Page 的 value 是对象
                QJsonObject obj = value.toObject();
                if (obj.contains("Home")) {
                    QJsonValue value = obj.value("Home");
                    if (value.isString()) {
                        QString strHome = value.toString();
                        qDebug() << "Home : " << strHome;
                    }
                }
                if (obj.contains("Download")) {
                    QJsonValue value = obj.value("Download");
                    if (value.isString()) {
                        QString strDownload = value.toString();
                        qDebug() << "Download : " << strDownload;
                    }
                }
                if (obj.contains("Developers")) {
                    QJsonValue value = obj.value("Developers");
                    if (value.isString()) {
                        QString strDevelopers = value.toString();
                        qDebug() << "Developers : " << strDevelopers;
                    }
                }
            }
        }
    }
}

这些是基本用法,比较简单,但细节至关重要。 建议在处理过程中启用严格模式。 例如:首先使用::判断转换后的JSON文档是否正确,然后进行解析。 解析过程中,首先判断是否是()等对应类型,然后通过()进行转换。

© 版权声明
评论 抢沙发
加载中~
每日一言
不怕万人阻挡,只怕自己投降
Not afraid of people blocking, I'm afraid their surrender