QT解析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 Json_GROUND_METE_AREA{
QString code;
QString msg;
struct Data {
struct Values {
QString station_id; //站点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 {
// 在这里处理结构体 A 的数据
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;
}
原文地址:https://blog.csdn.net/CodeWorld1999/article/details/139324821
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!