QT解析JSON格式超简单

目录

还是从最基础开始、什么是JSON

一、只解析json

 1..解析JSON的主要类

 2.主函数

二、解析并利用结构体存储

1.定义结构体

2.从 JSON 解析并填充结构体

实战示例


还是从最基础开始、什么是JSON

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它基于ECMAScript的一个子集,采用完全独立于语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得JSON成为理想的数据交换语言。

JSON 的基本结构包括两种:

对象(在 JavaScript 中用花括号 {} 表示)

一个对象由一对大括号 {} 包围,对象内的属性是键值对的形式,键(key)和值(value)之间用冒号 : 分隔,多个键值对之间用逗号 , 分隔。

示例

{ "name": "John", "age": 30, "city": "New York" }

数组(在 JavaScript 中用方括号 [] 表示)

一个数组由一对方括号 [] 包围,数组中的元素可以是任意类型的值(包括对象或数组),多个元素之间用逗号 , 分隔。

示例:

[ { "name": "John", "age": 30 }, { "name": "Jane", "age": 25 } ]

在 JSON 中,字符串必须使用双引号 "" 包围,不能使用单引号 ''。对象的键(key)也必须是字符串,并且用双引号包围。

除了对象和数组,JSON 还支持以下数据类型:

  • 字符串(string)
  • 数字(number)
  • 对象(object)
  • 数组(array)
  • 布尔值(true/false)
  • null

注意:JSON 不支持 JavaScript 中的函数、日期对象等复杂类型。

一、只解析json

示例JSON

假设我们有一个JSON文件data.json,内容如下:

{
    "name": "John Doe",
    "age": 30,
    "address": {
        "street": "1234 Elm Street",
        "city": "Somewhere",
        "zipcode": "12345"
    },
    "phones": [
        {"type": "home", "number": "123-456-7890"},
        {"type": "work", "number": "098-765-4321"}
    ]
}

 1..解析JSON的主要类

#include <QCoreApplication>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValue>
#include <QDebug>

class JsonParser {
public:
    JsonParser(const QString& filePath) : filePath(filePath) {}

    void parse() {
        QFile file(filePath);
        if (!file.open(QIODevice::ReadOnly)) {
            qWarning() << "Could not open file" << filePath;
            return;
        }

        QByteArray data = file.readAll();
        QJsonDocument doc = QJsonDocument::fromJson(data);

        if (!doc.isObject()) {
            qWarning() << "Invalid JSON format";
            return;
        }

        QJsonObject rootObj = doc.object();
        parseObject(rootObj);
    }

private:
    QString filePath;

    void parseObject(const QJsonObject& obj) {
        for (const QString& key : obj.keys()) {
            QJsonValue value = obj.value(key);
            if (value.isObject()) {
                qDebug() << "Object:" << key;
                parseObject(value.toObject());
            } else if (value.isArray()) {
                qDebug() << "Array:" << key;
                parseArray(value.toArray());
            } else {
                qDebug() << key << ":" << value.toVariant().toString();
            }
        }
    }

    void parseArray(const QJsonArray& arr) {
        for (const QJsonValue& value : arr) {
            if (value.isObject()) {
                parseObject(value.toObject());
            } else if (value.isArray()) {
                parseArray(value.toArray());
            } else {
                qDebug() << value.toVariant().toString();
            }
        }
    }
};

 2.主函数

#include <QCoreApplication>
#include "jsonparser.h"

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

    QString filePath = "data.json";  // JSON文件路径
    JsonParser parser(filePath);
    parser.parse();

    return a.exec();
}

这样利用嵌套的方法,就可以遍历所有的JSON的节点,输出所有的值,当然这个时候没有办法存储,只是解析出来内容,如果想要通过一个结构体来存储解析出来的所有数据,并且结构体需要合适的话,就需要声明好正确的结构体。

二、解析并利用结构体存储

示例JSON

假设我们有以下 JSON 数据:

{
    "name": "John Doe",
    "age": 30,
    "address": {
        "street": "123 Main St",
        "city": "Anytown",
        "zip": "12345"
    },
    "phone_numbers": [
        {"type": "home", "number": "555-555-5555"},
        {"type": "work", "number": "555-555-5556"}
    ]
}

 那么我们需要按照这个json格式来定义好结构体,用于存储解析出来的内容

1.定义结构体

#include <QString>
#include <QVector>

struct PhoneNumber {
    QString type;
    QString number;
};

struct Address {
    QString street;
    QString city;
    QString zip;
};

struct Person {
    QString name;
    int age;
    Address address;
    QVector<PhoneNumber> phoneNumbers;
};

2.从 JSON 解析并填充结构体

#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QFile>
#include <QDebug>

bool parseJsonToPerson(const QString& jsonString, Person& person) {
    QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8());
    if (doc.isNull() || !doc.isObject()) {
        qWarning() << "Failed to parse JSON";
        return false;
    }

    QJsonObject obj = doc.object();

    person.name = obj["name"].toString();
    person.age = obj["age"].toInt();

    QJsonObject addressObj = obj["address"].toObject();
    person.address.street = addressObj["street"].toString();
    person.address.city = addressObj["city"].toString();
    person.address.zip = addressObj["zip"].toString();

    QJsonArray phoneArray = obj["phone_numbers"].toArray();
    for (const QJsonValue& val : phoneArray) {
        QJsonObject phoneObj = val.toObject();
        PhoneNumber phone;
        phone.type = phoneObj["type"].toString();
        phone.number = phoneObj["number"].toString();
        person.phoneNumbers.append(phone);
    }

    return true;
}

int main() {
    QString jsonString = R"({
        "name": "John Doe",
        "age": 30,
        "address": {
            "street": "123 Main St",
            "city": "Anytown",
            "zip": "12345"
        },
        "phone_numbers": [
            {"type": "home", "number": "555-555-5555"},
            {"type": "work", "number": "555-555-5556"}
        ]
    })";

    Person person;
    if (parseJsonToPerson(jsonString, person)) {
        qDebug() << "Name:" << person.name;
        qDebug() << "Age:" << person.age;
        qDebug() << "Address:" << person.address.street << person.address.city << person.address.zip;
        for (const PhoneNumber& phone : person.phoneNumbers) {
            qDebug() << "Phone:" << phone.type << phone.number;
        }
    } else {
        qDebug() << "Failed to parse JSON.";
    }

    return 0;
}

 之后的问题就是看JSON的复杂程度了,因为JSON所有的内容很少,解析也只有这么些,但是如果JSON串很复杂,比如数组嵌套节点嵌套数组等等,就需要按照上方的方法,像解锁一样一层一层的解开,只是需要读懂json,但绝不是难的。

实战示例

这里就举例一个结构体嵌套结构体来存储JSON的实战示例吧

结构体定义为

struct RefineNumericalValuesElems
{
    RefineNumericalValuesElems() {}
    QString RH; 
    QString SNOW; 
    QString WW;
    QString VV; 
    QString UU100;
    QString CH;
    QString UU;
    QString SDEPTH;
    QString LSRAIN;
    QString TCC;
    QString VV10;
    QString HH;
    QString PS;
    QString DT;
    QString VIS;
    QString UU10;
    QString LCC; 
    QString TT; 
    QString RAIN; 
    QString CRAIN;
    QString HCC;
    QString TT2;
    QString STT;
    QString MSLP;
    QString CAPE;
    QString SH;
    QString SSTT;
    QString WG3H10M;
    QString VV100; 
    QString DEG0;
    QString VO; 
    QString DO; 

    void showInfo() const {
        qDebug() << "RH:" << RH;
        qDebug() << "SNOW:" << SNOW;
        qDebug() << "WW:" << WW;
        qDebug() << "VV:" << VV;
        qDebug() << "UU100:" << UU100;
        qDebug() << "CH:" << CH;
        qDebug() << "UU:" << UU;
        qDebug() << "SDEPTH:" << SDEPTH;
        qDebug() << "LSRAIN:" << LSRAIN;
        qDebug() << "TCC:" << TCC;
        qDebug() << "VV10:" << VV10;
        qDebug() << "HH:" << HH;
        qDebug() << "PS:" << PS;
        qDebug() << "DT:" << DT;
        qDebug() << "VIS:" << VIS;
        qDebug() << "UU10:" << UU10;
        qDebug() << "LCC:" << LCC;
        qDebug() << "TT:" << TT;
        qDebug() << "RAIN:" << RAIN;
        qDebug() << "CRAIN:" << CRAIN;
        qDebug() << "HCC:" << HCC;
        qDebug() << "TT2:" << TT2;
        qDebug() << "STT:" << STT;
        qDebug() << "MSLP:" << MSLP;
        qDebug() << "CAPE:" << CAPE;
        qDebug() << "SH:" << SH;
        qDebug() << "SSTT:" << SSTT;
        qDebug() << "WG3H10M:" << WG3H10M;
        qDebug() << "VV100:" << VV100;
        qDebug() << "DEG0:" << DEG0;
        qDebug() << "VO:" << VO;
        qDebug() << "DO:" << DO;
    }
};

struct GroundMeteorologyElems {
    QString clo_cov_lm; 
    QString clo_cov_low; 
    QString clo_height_lom; 
    QString td; 
    QString rh; 
    QString mslp; 
    QString rain_1h; 
    QString rain_3h; 
    QString rain_6h; 
    QString rain_12h;
    QString rain_24h; 
    QString pressure; 
    QString pressure_change_24h; 
    QString pressure_change_3h; 
    QString tt; 
    QString temp_change_24h; 
    QString temp_max_24h;
    QString temp_min_24h; 
    QString vis_human; 
    QString weather;
    QString wd_avg_10mi;
    QString wd_avg_2mi; 
    QString ws_avg_10mi;
    QString ws_avg_2mi;
    void showInfo() const {
        qDebug() << "clo_cov_lm:" << clo_cov_lm;
        qDebug() << "clo_cov_low:" << clo_cov_low;
        qDebug() << "clo_height_lom:" << clo_height_lom;
        qDebug() << "td:" << td;
        qDebug() << "rh:" << rh;
        qDebug() << "mslp:" << mslp;
        qDebug() << "rain_1h:" << rain_1h;
        qDebug() << "rain_3h:" << rain_3h;
        qDebug() << "rain_6h:" << rain_6h;
        qDebug() << "rain_12h:" << rain_12h;
        qDebug() << "rain_24h:" << rain_24h;
        qDebug() << "pressure:" << pressure;
        qDebug() << "pressure_change_24h:" << pressure_change_24h;
        qDebug() << "pressure_change_3h:" << pressure_change_3h;
        qDebug() << "tt:" << tt;
        qDebug() << "temp_change_24h:" << temp_change_24h;
        qDebug() << "temp_max_24h:" << temp_max_24h;
        qDebug() << "temp_min_24h:" << temp_min_24h;
        qDebug() << "vis_human:" << vis_human;
        qDebug() << "weather:" << weather;
        qDebug() << "wd_avg_10mi:" << wd_avg_10mi;
        qDebug() << "wd_avg_2mi:" << wd_avg_2mi;
        qDebug() << "ws_avg_10mi:" << ws_avg_10mi;
        qDebug() << "ws_avg_2mi:" << ws_avg_2mi;
    }
};

struct WAFSForecastElems {
    QString CAT;
    QString CBE;
    QString CBTOP;
    void showInfo() const{
        qDebug() << "CAT:" << CAT;
        qDebug() << "CBE:" << CBE;
        qDebug() << "CBTOP:" << CBTOP;
    }
};

struct Json_GROUND_METE_AREA{
    QString code;
    QString msg;
    struct Data {
            struct Values {
                QString station_id; 
                QString name; 
                QString lon; 
                QString record_time; 
                QString alti; 
                QString lat;
                //要素组
                RefineNumericalValuesElems refineNumericalValuesElems;
                GroundMeteorologyElems groundMeteorologyElems;
                WAFSForecastElems wafsForecastElems;
            };
            QVector<Values> values;
    } data;
    void showInfo() const {
        qDebug() << "Json_GROUND_METE_AREA: \n";
        qDebug() << "Code:" << code;
        qDebug() << "Message:" << msg;

        for (const Data::Values &value : data.values) {
            qDebug() << "Values List:";
            qDebug() << "station_id:" << value.station_id;
            qDebug() << "name:" << value.name;
            qDebug() << "lon:" << value.lon;
            qDebug() << "record_time:" << value.record_time;
            qDebug() << "alti:" << value.alti;
            qDebug() << "lat:" << value.lat;
            value.refineNumericalValuesElems.showInfo();
            value.groundMeteorologyElems.showInfo();
            value.wafsForecastElems.showInfo();
        }
    }
};

解析函数

void Widget::parseRefineNumericalValuesElems(const QJsonObject &obj, RefineNumericalValuesElems &elems) {
    QMap<QString, QString*> map = {
        {"RH", &elems.RH},
        {"SNOW", &elems.SNOW},
        {"WW", &elems.WW},
        {"VV", &elems.VV},
        {"UU100", &elems.UU100},
        {"CH", &elems.CH},
        {"UU", &elems.UU},
        {"SDEPTH", &elems.SDEPTH},
        {"LSRAIN", &elems.LSRAIN},
        {"TCC", &elems.TCC},
        {"VV10", &elems.VV10},
        {"HH", &elems.HH},
        {"PS", &elems.PS},
        {"DT", &elems.DT},
        {"VIS", &elems.VIS},
        {"UU10", &elems.UU10},
        {"LCC", &elems.LCC},
        {"TT", &elems.TT},
        {"RAIN", &elems.RAIN},
        {"CRAIN", &elems.CRAIN},
        {"HCC", &elems.HCC},
        {"TT2", &elems.TT2},
        {"STT", &elems.STT},
        {"MSLP", &elems.MSLP},
        {"CAPE", &elems.CAPE},
        {"SH", &elems.SH},
        {"SSTT", &elems.SSTT},
        {"WG3H10M", &elems.WG3H10M},
        {"VV100", &elems.VV100},
        {"DEG0", &elems.DEG0},
        {"VO", &elems.VO},
        {"DO", &elems.DO}
    };

    for (auto it = map.begin(); it != map.end(); ++it) {
        if (obj.contains(it.key())) {
            *(it.value()) = obj[it.key()].toVariant().toString();
        }
    }
}

void Widget::parseGroundMeteorologyElems(const QJsonObject &obj, GroundMeteorologyElems &elems)
{
    QMap<QString, QString*> map = {
        {"clo_cov_lm", &elems.clo_cov_lm},
        {"clo_cov_low", &elems.clo_cov_low},
        {"clo_height_lom", &elems.clo_height_lom},
        {"td", &elems.td},
        {"rh", &elems.rh},
        {"mslp", &elems.mslp},
        {"rain_1h", &elems.rain_1h},
        {"rain_3h", &elems.rain_3h},
        {"rain_6h", &elems.rain_6h},
        {"rain_12h", &elems.rain_12h},
        {"rain_24h", &elems.rain_24h},
        {"pressure", &elems.pressure},
        {"pressure_change_24h", &elems.pressure_change_24h},
        {"pressure_change_3h", &elems.pressure_change_3h},
        {"tt", &elems.tt},
        {"temp_change_24h", &elems.temp_change_24h},
        {"temp_max_24h", &elems.temp_max_24h},
        {"temp_min_24h", &elems.temp_min_24h},
        {"vis_human", &elems.vis_human},
        {"weather", &elems.weather},
        {"wd_avg_10mi", &elems.wd_avg_10mi},
        {"wd_avg_2mi", &elems.wd_avg_2mi},
        {"ws_avg_10mi", &elems.ws_avg_10mi},
        {"ws_avg_2mi", &elems.ws_avg_2mi}
    };

    for (auto it = map.begin(); it != map.end(); ++it) {
        if (obj.contains(it.key())) {
            *(it.value()) = obj[it.key()].toVariant().toString();
        }
    }
}

void Widget::parseWAFSForecastElems(const QJsonObject &obj, WAFSForecastElems &elems)
{
    QMap<QString, QString*> map = {
        {"CAT", &elems.CAT},
        {"CBE", &elems.CBE},
        {"CBTOP", &elems.CBTOP}
    };

    for (auto it = map.begin(); it != map.end(); ++it) {
        if (obj.contains(it.key())) {
            *(it.value()) = obj[it.key()].toVariant().toString();
        }
    }
}


Json_GLOBAL_REGIONAL_GROUND_METE Widget::parseGlobalRegionalGroundMeteData(const QByteArray &response)
{
    Json_GLOBAL_REGIONAL_GROUND_METE jsonToStructdata;
    QJsonDocument doc = QJsonDocument::fromJson(response);
    QJsonObject rootObj = doc.object();

    jsonToStructdata.code = rootObj["code"].toVariant().toString();
    jsonToStructdata.msg = rootObj["msg"].toVariant().toString();
        // 获取data对象
        QJsonObject dataObject = rootObj["data"].toObject();
        // 获取values字段
//        QJsonObject valuesObject = dataObject["values"].toObject();
        QJsonArray valuesArray = dataObject.value("values").toArray();
        // 将values字段的数据填充到结构体中
         for (const QJsonValue &val : valuesArray) {
             QJsonObject valueObj = val.toObject();
            Json_GROUND_METE_AREA::Data::Values value;
            value.station_id = valueObj["station_id"].toVariant().toString();
            value.name = valueObj["name"].toVariant().toString();
            value.lon = valueObj["lon"].toVariant().toString();
            value.record_time = valueObj["record_time"].toVariant().toString();
            value.alti = valueObj["alti"].toVariant().toString();
            value.lat = valueObj["lat"].toVariant().toString();
            parseRefineNumericalValuesElems(valueObj, value.refineNumericalValuesElems);
            parseGroundMeteorologyElems(valueObj, value.groundMeteorologyElems);
            parseWAFSForecastElems(valueObj, value.wafsForecastElems);
            jsonToStructdata.data.values.append(value);
        }
//    jsonToStructdata.showInfo();
    return jsonToStructdata;
}

<think> 我们正在讨论如何使用Qt解析JSON数据。根据引用,Qt从5.0开始提供了对JSON的支持,主要使用四个类:QJsonDocument、QJsonObject、QJsonArray和QJsonValue。以下将详细介绍解析步骤和方法。 ### 一、Qt JSON解析核心类 根据引用[1][3][4],Qt JSON解析主要依赖以下类: 1. **QJsonDocument**:读写JSON文档的接口,可将JSON数据转换为可操作对象[^1][^4] 2. **QJsonObject**:封装JSON对象(键值对集合),键为字符串,值为JSON支持的类型[^3] 3. **QJsonArray**:封装JSON数组(值的有序列表)[^4] 4. **QJsonValue**:封装JSON支持的数据类型(包括字符串、数字、布尔值、数组、对象等)[^1] ### 二、JSON解析步骤 参考引用[1][4]的代码示例,标准解析流程如下: #### 1. 读取原始JSON数据 ```cpp // 从网络回复读取数据(示例见引用[4]) QByteArray data = replay->readAll(); // 或直接使用字符串(示例见引用[5]) QString str = "{\"name\":\"xiaotang\", \"age\":\"23\"}"; QByteArray data = str.toUtf8(); ``` #### 2. 转换为QJsonDocument 使用`QJsonDocument::fromJson()`解析原始数据: ```cpp QJsonParseError jsonError; // 错误信息对象 QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); // 检查解析错误 if(jsonError.error != QJsonParseError::NoError) { qDebug() << "JSON格式错误:" << jsonError.errorString(); return; } ``` #### 3. 判断文档类型并获取根对象 JSON文档有两种类型:对象(`{}`)或数组(`[]`): ```cpp if(jsonDoc.isObject()) { // 根节点是对象 QJsonObject rootObj = jsonDoc.object(); parseObject(rootObj); // 自定义解析函数 } else if(jsonDoc.isArray()) { // 根节点是数组 QJsonArray rootArray = jsonDoc.array(); parseArray(rootArray); // 自定义解析函数 } ``` ### 三、数据提取方法 #### 1. 解析JSON对象(QJsonObject) 引用[3][4]展示了对象解析: ```cpp void parseObject(const QJsonObject &obj) { // 检查键是否存在 if(obj.contains("Name")) { // 获取值并判断类型 QJsonValue nameValue = obj.value("Name"); if(nameValue.isString()) { QString name = nameValue.toString(); qDebug() << "Name:" << name; // 输出: Name: "Qt" } } // 直接取值(简化版) int year = obj["From"].toInt(); // 直接转换为int bool crossPlatform = obj["Cross Platform"].toBool(); } ``` #### 2. 解析JSON数组(QJsonArray) 引用[5]中的数组解析示例: ```cpp // 解析引用[5]中的chi数组 QJsonArray chiArray = rootObj["chi"].toArray(); for(int i = 0; i < chiArray.size(); i++) { QJsonObject item = chiArray[i].toObject(); QString a = item["a"].toString(); // 输出: 第一项"aa", 第二项"aaa" QString b = item["b"].toString(); // 输出: 第一项"bb", 第二项"bbb" } ``` ### 四、完整解析示例(引用[4]网络请求场景) ```cpp void MainWindow::replyFinished(QNetworkReply* replay) { if(replay->error() == QNetworkReply::NoError) { QByteArray data = replay->readAll(); QJsonParseError jsonError; QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); if(jsonError.error == QJsonParseError::NoError) { if(jsonDoc.isObject()) { QJsonObject rootObj = jsonDoc.object(); if(rootObj.contains("weatherinfo")) { QJsonValue weatherValue = rootObj.value("weatherinfo"); if(weatherValue.isObject()) { QJsonObject weatherObj = weatherValue.toObject(); // 转换为QVariantMap便于使用 QVariantMap weatherMap = weatherObj.toVariantMap(); QString city = weatherMap["city"].toString(); qDebug() << "城市:" << city; } } } } } } ``` ### 五、常见错误处理 1. **键不存在时的处理** ```cpp // 安全取值方法 if(obj.contains("key") && obj["key"].isString()) { QString value = obj["key"].toString(); } ``` 2. **类型转换失败** ```cpp QJsonValue value = obj.value("age"); if(value.isString()) { // 即使数字也可能被解析为字符串 bool ok; int age = value.toString().toInt(&ok); if(!ok) qDebug() << "age转换失败"; } ``` 3. **嵌套对象/数组访问** ```cpp // 访问深层数据:data.list[0].id if(rootObj.contains("data") && rootObj["data"].isObject()) { QJsonObject dataObj = rootObj["data"].toObject(); if(dataObj.contains("list") && dataObj["list"].isArray()) { QJsonArray listArray = dataObj["list"].toArray(); if(listArray.size() > 0 && listArray[0].isObject()) { QJsonObject item = listArray[0].toObject(); int id = item["id"].toInt(); } } } ``` > **关键点**:Qt JSON解析采用链式安全访问,必须逐层检查类型和键是否存在[^4]。 ### 六、JSON生成方法 引用[3]展示了如何构建JSON: ```cpp // 创建JSON对象 QJsonObject json; json.insert("Name", "Qt"); json.insert("From", 2016); json.insert("Cross Platform", true); // 添加数组 QJsonArray versions; versions.append(5.9); versions.append(5.12); versions.append(6.0); json.insert("Versions", versions); // 转换为文档 QJsonDocument jsonDoc(json); QString jsonString = jsonDoc.toJson(); // 生成JSON字符串 ``` ### 性能优化建议 1. **避免大文件解析阻塞UI线程**:网络请求或大文件解析使用`QCoreApplication::processEvents()`分块处理 2. **减少临时对象**:尽量使用`const QJsonObject&`传递引用 3. **二进制存储**:对重复使用的JSON数据,用`jsonDoc.toBinaryData()`保存为二进制格式加快加载 §§相关问题§§ 1. Qt中如何实现JSON数据与自定义对象的相互转换? 2. 如何处理JSON解析中的编码问题(如中文乱码)? 3. Qt网络请求(QNetworkAccessManager)如何与JSON解析结合使用? [^1]: QT——JSON解析 [^2]: QT Json解析方法 [^3]: Qt--解析Json [^4]: Qt解析Json的总结 [^5]: Qt解析JSON数据 </think> ### Qt JSON解析方法详解 根据引用内容,Qt从5.0开始提供原生JSON支持,主要使用以下四个核心类进行解析: #### 一、关键JSON解析类 | 类名 | 功能 | 示例代码 | |------|------|----------| | `QJsonDocument` | JSON文档读写入口 | `QJsonDocument::fromJson(data, &error)`[^4] | | `QJsonObject` | 封装JSON对象(键值对集合) | `json.insert("Name", "Qt")`[^3] | | `QJsonArray` | 封装JSON数组(有序值列表) | `QJsonArray versions = {5.9, 5.12, 6.0}` | | `QJsonValue` | 封装JSON支持的数据类型 | `if(obj["weatherinfo"].isObject())`[^4] | #### 二、标准解析流程 1. **准备原始数据** ```cpp // 从网络获取(引用[4]示例) QByteArray data = replay->readAll(); // 或直接定义字符串(引用[5]示例) QString str = R"({"name":"xiaotang", "age":23, "languages":["C++", "Python"]})"; ``` 2. **转换为JSON文档** ```cpp QJsonParseError jsonError; // 错误处理对象 QJsonDocument jsonDoc = QJsonDocument::fromJson(data.toUtf8(), &jsonError); if(jsonError.error != QJsonParseError::NoError) { // 检查格式错误 qDebug() << "JSON格式错误:" << jsonError.errorString(); return; } ``` 3. **获取根对象/数组** ```cpp if(jsonDoc.isObject()) { // 根节点是对象 QJsonObject rootObj = jsonDoc.object(); parseObject(rootObj); } else if(jsonDoc.isArray()) { // 根节点是数组 QJsonArray rootArray = jsonDoc.array(); parseArray(rootArray); } ``` 4. **递归解析嵌套结构** ```cpp void parseObject(const QJsonObject &obj) { // 获取字符串值 if(obj.contains("name")) { QString name = obj["name"].toString(); qDebug() << "Name:" << name; } // 获取嵌套对象 if(obj.contains("weatherinfo") && obj["weatherinfo"].isObject()) { QJsonObject weather = obj["weatherinfo"].toObject(); parseObject(weather); // 递归解析 } // 获取数组 if(obj.contains("languages") && obj["languages"].isArray()) { QJsonArray langArray = obj["languages"].toArray(); for(const QJsonValue &val : langArray) { qDebug() << "Language:" << val.toString(); } } } ``` #### 三、完整网络请求解析示例 基于引用[4]的增强实现: ```cpp void handleNetworkReply(QNetworkReply* reply) { if(reply->error() == QNetworkReply::NoError) { QByteArray data = reply->readAll(); QJsonParseError jsonError; QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); if(jsonError.error == QJsonParseError::NoError) { if(jsonDoc.isObject()) { QJsonObject root = jsonDoc.object(); if(root.contains("weatherinfo")) { QJsonObject weather = root["weatherinfo"].toObject(); // 安全提取数据 QString city = weather.value("city").toString("Unknown"); double temp = weather.value("temp").toDouble(0.0); qDebug() << city << "当前温度:" << temp << "℃"; } } } else { qWarning() << "JSON解析错误:" << jsonError.errorString(); } } else { qCritical() << "网络错误:" << reply->errorString(); } reply->deleteLater(); // 清理资源 } ``` #### 四、常见问题解决方案 1. **中文乱码处理** ```cpp // 设置全局编码(main函数中) QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); ``` 2. **类型安全访问** ```cpp // 安全获取值(避免崩溃) int age = obj.value("age").toInt(-1); // -1表示默认值 if(age == -1) qWarning() << "age字段缺失或类型错误"; ``` 3. **动态键名处理** ```cpp QStringList keys = obj.keys(); for(const QString &key : keys) { QJsonValue val = obj.value(key); if(val.isString()) { qDebug() << key << ":" << val.toString(); } } ``` #### 五、性能优化建议 1. **避免深度嵌套**:JSON层级不宜过5层 2. **使用二进制格式**:频繁读写时用`QJsonDocument::toBinaryData()` 3. **异步解析**:大文件使用`QtConcurrent::run()`在后台线程解析 4. **内存管理**:及时释放`QNetworkReply`对象(`deleteLater()`) > 最佳实践:对于过1MB的JSON文件,建议使用流式解析器(如`QJsonStreamReader`)替代DOM解析[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值