QT——JSON解析

一些相关知识的链接:

有关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——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<<"℃";
	}
}
上一篇:启动MFC程序的时候报错:0xC0000005: 读取位置 0x00000000 时发生访问冲突


下一篇:中国月儿明,英国屋漏偏逢连夜雨 | 经济学人早报精选