在 Qt 中构建和解析多层嵌套的 JSON 数据

随着现代应用程序的发展,JSON(JavaScript Object Notation)成为了前后端通信中非常常用的数据交换格式。JSON 以其轻量级、可读性强的特点广泛用于 RESTful API 以及 Web 服务的通信。对于复杂的数据结构,JSON 能够通过对象嵌套和数组嵌套来表示。在 Qt 中,我们可以使用 QJsonObjectQJsonArrayQJsonDocument 来构建和解析多层嵌套的 JSON 数据。本文将详细介绍如何在 Qt 中处理这些复杂的 JSON 结构。


一. 如何解析多层嵌套的 JSON 数据

当从服务器获取复杂的 JSON 数据时,可能会遇到多层嵌套的结构。假设服务器返回如下的嵌套 JSON 数据:

复制代码
{
    "student": {
        "name": "John",
        "age": 21,
        "sex": "Male",
        "address": {
            "city": "New York",
            "zip": "10001"
        }
    },
    "class": "Physics"
}

这种 JSON 数据包含一个 student 对象,而 student 对象内部又嵌套了一个 address 对象。为了解析这样的 JSON 数据,我们需要递归地提取每一层的对象和字段。

解析多层 JSON 的代码示例
cpp 复制代码
#include <QCoreApplication>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>
#include <QDebug>

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    // 模拟一个多层的 JSON 响应
    QByteArray jsonResponse = R"({
        "student": {
            "name": "John",
            "age": 21,
            "sex": "Male",
            "address": {
                "city": "New York",
                "zip": "10001"
            }
        },
        "class": "Physics"
    })";

    // 解析 JSON 文档
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonResponse);

    if (jsonDoc.isObject()) {
        QJsonObject rootObject = jsonDoc.object();

        // 获取 'student' 对象
        if (rootObject.contains("student") && rootObject["student"].isObject()) {
            QJsonObject studentObject = rootObject["student"].toObject();

            // 提取 'name' 字段
            if (studentObject.contains("name") && studentObject["name"].isString()) {
                QString name = studentObject["name"].toString();
                qDebug() << "Student Name:" << name;
            }

            // 提取 'age' 字段
            if (studentObject.contains("age") && studentObject["age"].isDouble()) {
                int age = studentObject["age"].toInt();
                qDebug() << "Student Age:" << age;
            }

            // 提取 'sex' 字段
            if (studentObject.contains("sex") && studentObject["sex"].isString()) {
                QString sex = studentObject["sex"].toString();
                qDebug() << "Student Sex:" << sex;
            }

            // 提取嵌套的 'address' 对象
            if (studentObject.contains("address") && studentObject["address"].isObject()) {
                QJsonObject addressObject = studentObject["address"].toObject();

                if (addressObject.contains("city") && addressObject["city"].isString()) {
                    QString city = addressObject["city"].toString();
                    qDebug() << "City:" << city;
                }

                if (addressObject.contains("zip") && addressObject["zip"].isString()) {
                    QString zip = addressObject["zip"].toString();
                    qDebug() << "ZIP Code:" << zip;
                }
            }
        }

        // 获取根级字段 'class'
        if (rootObject.contains("class") && rootObject["class"].isString()) {
            QString className = rootObject["class"].toString();
            qDebug() << "Class:" << className;
        }
    }

    return a.exec();
}
解析步骤说明
  1. 加载 JSON 文档 :使用 QJsonDocument::fromJson() 将 JSON 数据转换为 QJsonDocument
  2. 判断 JSON 类型 :检查 QJsonDocument 是否是对象类型,通过 jsonDoc.object() 提取根对象。
  3. 递归解析对象 :对嵌套的对象逐层解析,如提取 student 对象中的 nameage 等字段。
  4. 解析嵌套对象 :通过 studentObject["address"].toObject() 获取嵌套的 address 对象,然后进一步提取其中的字段。
  5. 解析顶层字段 :提取 class 这样的根级字段与嵌套对象的解析方法类似。

二. 如何构建多层嵌套的 JSON 数据

构建多层嵌套的 JSON 数据与解析类似,通过 QJsonObjectQJsonArray 可以轻松构建复杂的 JSON 结构。例如,我们构建一个嵌套的 JSON,如下所示:

cpp 复制代码
{
    "student": {
        "name": "John",
        "age": 21,
        "sex": "Male",
        "address": {
            "city": "New York",
            "zip": "10001"
        }
    },
    "class": "Physics"
}
构建多层嵌套 JSON 的代码示例
复制代码
cpp 复制代码
#include <QCoreApplication>
#include <QJsonObject>
#include <QJsonDocument>
#include <QDebug>

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    // 创建最里面的 address 对象
    QJsonObject addressObject;
    addressObject["city"] = "New York";
    addressObject["zip"] = "10001";

    // 创建 student 对象,并包含 name、age、sex 以及 address
    QJsonObject studentObject;
    studentObject["name"] = "John";
    studentObject["age"] = 21;
    studentObject["sex"] = "Male";
    studentObject["address"] = addressObject; // 嵌套的 address 对象

    // 创建根对象,并包含 student 对象和 class 字段
    QJsonObject rootObject;
    rootObject["student"] = studentObject;
    rootObject["class"] = "Physics";

    // 将 JSON 对象转换为 QJsonDocument
    QJsonDocument jsonDoc(rootObject);

    // 输出 JSON 字符串
    QByteArray jsonData = jsonDoc.toJson();
    qDebug() << jsonData;

    return a.exec();
}
构建步骤说明
  1. 创建嵌套对象 :首先创建最内层的 address 对象,然后将其嵌入到 student 对象中。
  2. 创建中间对象 :在 studentObject 中添加 nameagesex 字段,并嵌入 addressObject
  3. 创建根对象 :将 studentObjectclass 添加到根对象 rootObject 中。
  4. 转换为 JSON 字符串 :通过 QJsonDocument::toJson() 将构建好的 JSON 对象序列化为字符串或 QByteArray

三. 构建包含数组的多层 JSON 数据

有时,JSON 结构可能包含数组。你可以使用 QJsonArray 来表示 JSON 数组。例如,构建一个包含多个学生的 JSON 数据,每个学生都有一个嵌套的 address 对象:

cpp 复制代码
{
    "class": "Physics",
    "students": [
        {
            "name": "John",
            "age": 21,
            "sex": "Male",
            "address": {
                "city": "New York",
                "zip": "10001"
            }
        },
        {
            "name": "Alice",
            "age": 22,
            "sex": "Female",
            "address": {
                "city": "Los Angeles",
                "zip": "90001"
            }
        }
    ]
}
构建包含数组的 JSON 的代码示例
复制代码
cpp 复制代码
#include <QCoreApplication>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QDebug>

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    // 创建第一个学生的 address 对象
    QJsonObject addressObject1;
    addressObject1["city"] = "New York";
    addressObject1["zip"] = "10001";

    // 创建第一个 student 对象
    QJsonObject studentObject1;
    studentObject1["name"] = "John";
    studentObject1["age"] = 21;
    studentObject1["sex"] = "Male";
    studentObject1["address"] = addressObject1;

    // 创建第二个学生的 address 对象
    QJsonObject addressObject2;
    addressObject2["city"] = "Los Angeles";
    addressObject2["zip"] = "90001";

    // 创建第二个 student 对象
    QJsonObject studentObject2;
    studentObject2["name"] = "Alice";
    studentObject2["age"] = 22;
    studentObject2["sex"] = "Female";
    studentObject2["address"] = addressObject2;

    // 创建 students 数组
    QJsonArray studentsArray;
    studentsArray.append(studentObject1);
    studentsArray.append(studentObject2);

    // 创建根对象
    QJsonObject rootObject;
    rootObject["class"] = "Physics";
    rootObject["students"] = studentsArray;

    // 输出 JSON 字符串
    QJsonDocument jsonDoc(rootObject);
    QByteArray jsonData = jsonDoc.toJson();
    qDebug() << jsonData;

    return a.exec();
}
构建步骤说明
  1. 创建多个对象 :为每个学生创建一个 studentObject,并嵌入对应的 addressObject
  2. 创建数组 :使用 QJsonArray 存储多个 studentObject
  3. 将数组嵌入根对象 :将 studentsArray 嵌入到 rootObject 中,构建完整的 JSON 数据。

总结

Qt 提供了强大的 JSON 解析与构建工具,通过 QJsonObjectQJsonArrayQJsonDocument,你可以轻松处理复杂的嵌套 JSON 结构。无论是从服务器获取多层嵌套的 JSON 数据并进行解析,还是构建复杂的 JSON 数据并发送给服务器,Qt 都能很好地支持这一流程。

  • 解析 JSON :通过递归访问 QJsonObject,逐层提取数据,确保类型匹配以避免错误。
  • 构建 JSON :通过嵌套对象和数组来构建复杂的 JSON 结构,将其序列化为 QByteArray 或字符串以用于通信或存储。

使用 Qt 处理 JSON 数据,你可以方便地与 RESTful API 和 Web 服务进行交互,实现现代应用程序所需的复杂数据操作。

相关推荐
apocelipes1 天前
常用编程语言和库的正则表达式性能对比
c语言·c++·python·性能优化·golang·开发工具和环境
郝学胜_神的一滴2 天前
CMake 034:生成器表达式:解耦构建时序、精简分支逻辑的终极利器
c++·cmake
hez20103 天前
在 .NET 上构建超大托管数组
c#·.net·.net core·gc·clr
见过夏天3 天前
C++ 基础入门完全指南
c++
用户805533698034 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner4 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
BadBadBad__AK5 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
Venuslite5 天前
从 Unexpected token < 到 Extra data:一次讲清 JSON 解析错误的排查思路
json
卷无止境5 天前
Eigen 库如何借助 OpenMP 加速计算
c++·后端
卷无止境5 天前
OpenMPI、MPICH 与 OpenMP:关系、核心概念与架构全解
c++·后端