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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/22147.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2.4 OpenCV随手简记(五)

一、图像翻转 第一个图像翻转&#xff0c;这个可是制作表情包的利器。 图像翻转在 OpenCV 中调用函数 flip() 实现&#xff0c;原函数如下&#xff1a; flip(src, flipCode, dstNone) src&#xff1a;原始图像。 flipCode&#xff1a;翻转方向&#xff0c; 如果 flipCode 为…

【前端面试常见问题】防抖(Debounce)与节流(Throttle)

目录 一、概念阐释 1. 防抖(Debounce) 2. 节流(Throttle) 二、实现方法 防抖函数的实现 节流函数的实现 三、区别与选择 四、面试技巧 在前端开发领域&#xff0c;性能优化是一个永恒的话题&#xff0c;尤其是在处理高频率触发的事件时&#xff0c;如窗口的resize、scroll事…

[Redis]List类型

列表类型来存储多个有序的字符串&#xff0c;a、b、c、d、e 五个元素从左到右组成了一个有序的列表&#xff0c;列表中的每个字符串称为元素&#xff0c;一个列表最多可以存储个元素。在 Redis 中&#xff0c;可以对列表两端插入&#xff08;push&#xff09;和弹出&#xff08…

Element UI:高效的 Vue.js 组件库

Element UI&#xff1a;高效的 Vue.js 组件库 Element UI 是由饿了么前端团队开发的一个基于 Vue.js 的桌面端组件库。自从发布以来&#xff0c;Element UI 因其高质量的设计、丰富的功能和易于使用的特性&#xff0c;迅速成为 Vue.js 开发者中最受欢迎的 UI 框架之一。本文将…

【动手学深度学习】多层感知机之权重衰减研究详情

目录 &#x1f30a;1. 研究目的 &#x1f30a;2. 研究准备 &#x1f30a;3. 研究内容 &#x1f30d;3.1 多层感知机权重衰减 &#x1f30d;3.2 基础练习 &#x1f30a;4. 研究体会 &#x1f30a;1. 研究目的 防止过拟合&#xff1a;权重衰减和暂退法都是用来控制模型的复…

五年制转本中比较难考的几个专业

五年制转本中比较难考的几个专业&#xff0c;你们知道吗&#xff1f;第一个就是医学类相关专业&#xff0c;医学界都流传着一句话&#xff0c;劝人学医&#xff0c;天打雷劈&#xff0c;想必大家都有所耳闻。并且大家在选专业的时候&#xff0c;都会有人告诉你&#xff0c;千万…

北大、腾讯强推!DynamiCrafter WebUI 在线教程,无需逐帧记录即可图片变视频

从史前时期开始&#xff0c;人类的祖先就曾以石为笔&#xff0c;在洞穴的石壁描绘出一系列野牛奔跑的分析图&#xff0c;壁画上的动物被叠加了多条腿&#xff0c;用来表现连贯的动作&#xff0c;这或许便是动态视频的最早雏形。 被焚之城的山羊陶碗 时光流转&#xff0c;最初&…

sqli-labs 靶场闯关基础准备、学习步骤、SQL注入类型,常用基本函数、获取数据库元数据

Sqli-labs的主要作用是帮助用户学习如何识别和利用不同类型的SQL注入漏洞&#xff0c;并了解如何修复和防范这些漏洞。 它提供了多个不同的漏洞场景&#xff0c;每个场景都代表了一个特定类型的SQL注入漏洞。 用户可以通过攻击这些场景来学习和实践漏洞利用技术&#xff0c;以及…

使用国内源加速pip安装包

文章目录 pip国内镜像源临时使用设为默认 pip国内镜像源 清华&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple 阿里云&#xff1a;http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/ 华中理工大学&#xff1a;http://pyp…

【Linux】多进程基础--信号

文章目录 信号常见信号信号定时函数 信号 发生事件时通过信号向进程进行通知&#xff0c;在软件层次上模拟中断&#xff0c;也叫软件中断&#xff0c;处理优先级较高对于前台进程可以通过特殊的字符发送信号&#xff0c;例如CtrlC即给当前进程发送一个SIGINT中断信号。kill命令…

【数据结构】二叉树-堆

目录 一.树概念及性质 二.二叉树的概念与实现 三.堆的概念和结构 四.堆的实现 1.向下调整算法 2. 堆的创建 3.向上调整算法 4.堆的删除 五.堆排序 六.堆-源码 一.树概念及性质 树是一种非线性的数据结构&#xff0c;它是由数个节点组成的具有层次关系的集合。之所以叫…

干货 | SDR RFSoC技术框图大放送(附资源)

软件无线电(SDR) 本文参考《Software Defined Radio with Zynq UltraScale RFSoc》&#xff0c;全文共744页。需要的可以给公众号 迪普微科技 发送“SDR”。

【力扣】矩阵中的最长递增路径

一、题目描述 二、解题思路 1、先求出以矩阵中的每个单元格为起点的最长递增路径 题目中说&#xff0c;对于每个单元格&#xff0c;你可以往上&#xff0c;下&#xff0c;左&#xff0c;右四个方向移动。那么以一个单元格为起点的最长递增路径就是&#xff1a;从该单元格往上…

基于曲率的关键点检测

曲率是描述点云中每个点局部几何形状的一种度量。高曲率的点通常位于边缘、角点等显著位置。因此,通过检测曲率较高的点,我们可以找到点云中的关键点。 函数实现 下面是一个用于基于曲率检测关键点的函数实现 计算平均曲率 //计算平均曲率 float com_avg_curvature(pcl::P…

SpringBoot项目启动后访问网页显示“Please sign in“

SpringBoot启动类代码如下 SpringBoot项目启动后访问网页显示"Please sign in"&#xff0c;如图 这是一个安全拦截页面&#xff0c;即SpringSecurity认证授权页面&#xff0c;因为SecurityAutoConfiguration是Spring Boot提供的安全自动配置类&#xff0c;也就是说它…

城规跨考地信:你需要知道的几件事

24考研结束&#xff0c;25地信考研的小伙伴也开始准备。 在这期间发现一个现象&#xff0c;城规跨考GIS的讨论度非常高。 对这一点&#xff0c;我并不感到意外&#xff0c;因为随着地产行业的节节败退&#xff0c;很多单位不需要那么多规划人和建筑人&#xff0c;乃至土木人。…

SpringCloud 微服务中网关如何记录请求响应日志?

在基于SpringCloud开发的微服务中&#xff0c;我们一般会选择在网关层记录请求和响应日志&#xff0c;并将其收集到ELK中用作查询和分析。 今天我们就来看看如何实现此功能。 日志实体类 首先我们在网关中定义一个日志实体&#xff0c;用于组装日志对象 Data public class …

使用Java apache commons包五分钟搞定NCR解析(内附源码)

在网上看到很多关于解析NCR(Numeric Character Reference)字符串的java实现&#xff0c;核心都是通过自定义正则表达式来解析&#xff0c;其实org.apache.commons 已经为我们提供了jar包 解决该问题&#xff0c;非常的方便&#xff01;在这里我就来简单分享一下具体实现方法&am…

这就是英伟达 CEO 黄仁勋所说的人工智能“下一波浪潮”|TodayAI

在台湾一年一度的科技展 COMPUTEX 开幕前的周日&#xff0c;英伟达&#xff08;Nvidia&#xff09;首席执行官黄仁勋&#xff08;Jensen Huang&#xff09;表示&#xff0c;机器人和“理解物理定律的 AI”将成为下一波技术浪潮。他指出&#xff0c;英伟达目前正在推动生成式人工…

MyBatis核心对象

MyBatis核心类对象主要有俩个&#xff1a; 1&#xff1a;对相关配置文件信息进行封装的Configuration对象 2&#xff1a;用来执行数据库操作的Executor对象。 核心对象----存储类对象Configuration Configuration对象主要有三个作用&#xff1a; 1&#xff1a;封装MyBatis…