一些相关知识的链接:
有关JOSN相关的基础知识:JSON基础
有关QT中JSON的操作:QT中JSON的操作
一个在线工具,可以进行JSON格式化分析的网址:JSON格式化
如何从网络中轻松得到JSON数据?
可以通过访问心知天气的相关API,心知天气就会给我们返回一串JSON数据。例如在浏览器中打开以下网址(将下面的key值和location值换掉):
https://api.seniverse.com/v3/weather/daily.json?key=你在心知天气中的私钥&location=成都&language=zh-Hans&unit=c&start=0&days=5
然后就会返回如下格式的JSON数据:
从 Qt 5.0 开始提供了对 Json 的支持,我们可以直接使用 Qt 提供的 Json 类进行数据的组织和解析。相关的类常用的主要有四个,具体如下:
JSON类1 | 功能介绍 |
---|---|
QJsonDocument | 提供一种对JSON文档进行读和写的方法 ,比如将JSON格式的字符串转化为可以操作的JSON文档类。 |
QJsonObject | 封装了JSON对象。 |
QJsonArray | 封装了JSON数组。 |
QJsonValue | 封装了JSON支持的数据类型。 |
1、QT中JSON解析的步骤
先打一剂预防针:JSON解析是一个比较繁琐的过程,开始上手需要一定的耐心去学习。
JSON数据是由对象、数组、数据(键值对)封装而成。
现假设我们解析的JSON数据如下所示,最终我们要得到的是三天内的天气情况:
{
"results": [
{
"location": {
"id": "WM6N2PM3WY2K",
"name": "成都",
"country": "CN",
"path": "成都,成都,四川,中国",
"timezone": "Asia/Shanghai",
"timezone_offset": "+08:00"
},
"daily": [
{
"date": "2022-01-08",
"text_day": "雾",
"code_day": "30",
"text_night": "阴",
"code_night": "9",
"high": "10",
"low": "6",
"rainfall": "0.00",
"precip": "0.09",
"wind_direction": "西南",
"wind_direction_degree": "225",
"wind_speed": "8.4",
"wind_scale": "2",
"humidity": "95"
},
{
"date": "2022-01-09",
"text_day": "阴",
"code_day": "9",
"text_night": "小雨",
"code_night": "13",
"high": "10",
"low": "6",
"rainfall": "0.12",
"precip": "0.38",
"wind_direction": "无持续风向",
"wind_direction_degree": "",
"wind_speed": "8.4",
"wind_scale": "2",
"humidity": "97"
},
{
"date": "2022-01-10",
"text_day": "多云",
"code_day": "4",
"text_night": "晴",
"code_night": "1",
"high": "13",
"low": "3",
"rainfall": "0.00",
"precip": "0.09",
"wind_direction": "无持续风向",
"wind_direction_degree": "",
"wind_speed": "3.0",
"wind_scale": "1",
"humidity": "95"
}
],
"last_update": "2022-01-08T08:00:00+08:00"
}
]
}
看完之后一头雾水?不存在的,我带你一步步扒开它的外套。
1、先看整体框架是如何构成的
最外层是一个对象(对象1),然后对象1中只有一个数据(即键值对)。通过该类下的“result”键就可以获取到值(数组1),数组里面只有一个数据(对象2),对象2中含有三个数据,都是由是三个键值对组成。
{ //对象1
"results": [ //数组1
{ //对象2
"location":{位置信息},
"daily": [ {第一天的天气信息} , {第二天的天气信息} , {第三天的天气信息} ], //数组2
"last_update": "2022-01-08T08:00:00+08:00"
}
]
}
2、用JSON解析时,如何获取键为daily所对应的值呢?
- 先进入最外层的对象1;
- 通过键result查找对应的值,即数组1;
- 从数组中获取到下标为0的数据——对象2;
- 在对象2中,通过键dialy获取对应的值——数组2;
- 数组2中包含三个对象,可以通过遍历分别得到每个对象,并从对象中根据键值对的方法,获取到天气信息。
注:上面的分析很重要哦,应为编程时,就是按照上面的思路进行编写的。如果看不太懂,可以结合到下面给出的具体代码对比着看。
1、先用QJsonDocument类下的一个静态方法fromJson()将获取到的JSON数据转化为JSON文档。例如:
QJsonParseError jsonParseError; //创建一个JSON错误类,用于接收JSON解析错误的信息
QJsonDocument jsonDocument = QJsonDocument::fromJson(data1,&jsonParseError); //data1为获取到的JSON数据
2、从传回的JSON错误类中,判断是否出错。
if((jsonParseError.error != QJsonParseError::NoError)&&(jsonDocument.isNull()))
{
qDebug()<< "JSON格式错误";
return;
}
3、将JSON文档类进行转化为相应的JSON类型(有JOSN对象和JSON数组)。
这个转化要根据穿回来的JSON数据格式确定,比如传回来的JOSN数据最外层是“[ ]”(即JSON数据是由中括号扩起来的,表明是一个数组),则转化为JOSN数组类型;如果传回来的JOSN数据最外层是“{ }”(即传回来的JSON数据最外层是大括号,表明是一个对象),则转化为JSON对象。
从上面给出的JSON数据中可以看出,最外层为大括号,表示返回的是一个对象,所以这里第一步就要将JSON文档转化为一个JSON对象,然后再操作。
QJsonObject rootObject = jsonDocument.object(); //将文档对象中的数据转化为JSON对象,这里的JSON数据的最外层为对象;最外层若为数组,则要用jsonDocument.array()
4、对最外层的这个对象,一步一步的扒皮,然后获取到键“daily”所对应的值。
QJsonArray resultArray = rootObject.value("results").toArray(); //得到键为“result”所对应的值。观察知道这个值为数组,所以将其转换为JSON数组类型
QJsonObject resultArrayObject = resultArray.at(0).toObject(); //获取到数组下标0对应的数据,并将类型转化为JSON对象
QJsonArray dailyArray = resultArrayObject.value("daily").toArray(); //获取到键为“daily”所对应的值,并将类型转化为JSON数组
注: 在解析过程中,对每次得到的JSON数据,都要更转化为后面对应的JSON数据类型,是数组就转化为数组,是对象就转化为对象。
5、对这个JSON数组进行遍历,获取到其中的每个对象,并在每个对象中,更具键值对获取到每天的天气信息。
for(int i=0;i<dailyArray.count();i++) //对数组进行遍历
{
QJsonValue dailyArrayObject = dailyArray.at(i); //读取数组中第i个数据
if(dailyArrayObject.type() == QJsonValue::Object) //如果数组中的第i数据的类型是JSON类
{
QJsonObject dailyArrayObjectValue = dailyArrayObject.toObject(); //将数据转换为JSON类
//在类中根据键获取对应值
QJsonValue dateValue = dailyArrayObjectValue.value("date"); //获取时间,对应的键为“date”
QJsonValue text_dayValue = dailyArrayObjectValue.value("text_day"); //获取白天天气,对应的键为“text_day”
QJsonValue text_nightValue = dailyArrayObjectValue.value("text_night"); //获取晚上天气,对应的键为“text_night”
QJsonValue highValue = dailyArrayObjectValue.value("high"); //获取最高温度,对应的键为“high”
QJsonValue lowValue = dailyArrayObjectValue.value("low"); //获取最低温度,对应的键为“low”
//将值转化为对应的类型,并保存在结构体中
info[i].date = dateValue.toString();
info[i].text_day = text_dayValue.toString();
info[i].text_night = text_nightValue.toString();
info[i].high = highValue.toString().toInt();
info[i].low = lowValue.toString().toInt();
//调试输出看看
qDebug()<<"日期:"<<info[i].date;
qDebug()<<"白天天气:"<<info[i].text_day;
qDebug()<<"晚上天气:"<<info[i].text_night;
qDebug()<<"温度范围:"<<info[i].low<<"℃-"<<info[i].high<<"℃";
}
}