查看原文
其他

Qt平台下使用QJson解析JSON字符串

wcc149 电子电路开发学习 2021-01-31


前言

上一篇介绍了C语言写的JSON解析库cJSON的使用:使用cJSON库解析和构建JSON字符串

本篇文章介绍,Qt开发环境下QJson库的使用示例。示例代码包含简单和复杂JSON字符串的解析和构建,Qt工程已经开源在Github和Gitee代码托管平台。

  • Github仓库地址:

https://github.com/whik/QJson_Demo

  • Gitee仓库地址:

https://gitee.com/whik/QJson_Demo

开发平台基于Qt 5.8 Windows。示例的JSON字符串和上一篇使用的是一样的。

JSON解析示例包括:

  • 和风天气实时数据

  • 心知天气实时数据

  • 心知天气3天预报数据

  • 城市空气质量AQI信息

  • 全国油价信息

  • 北京时间等。

由于文章篇幅限制,本篇文章先介绍QJson的解析示例。

QJson解析JSON示例

JSON的解析要对照JSON字符串来理解,关于JSON字符串的介绍,可以参考JSON简介

解析和构建都要先包含如下头文件:

  1. #include <QJsonDocument>

  2. #include <QJsonObject>

  3. #include <QJsonArray>

示例字符串1:和风天气实时数据

这个JSON字符串中HeWeather6键的值是一个数组,数组内只有1个JSON对象,这个对象里又嵌套了几个JSON对象。

  1. {

  2. "HeWeather6": [{

  3. "basic": {

  4. "cid": "CN101010700",

  5. "location": "昌平",

  6. "parent_city": "北京",

  7. "admin_area": "北京",

  8. "cnty": "中国",

  9. "lat": "40.21808624",

  10. "lon": "116.23590851",

  11. "tz": "+8.00"

  12. },

  13. "update": {

  14. "loc": "2019-07-20 10:21",

  15. "utc": "2019-07-20 02:21"

  16. },

  17. "status": "ok",

  18. "now": {

  19. "cloud": "96",

  20. "cond_code": "104",

  21. "cond_txt": "阴",

  22. "fl": "28",

  23. "hum": "86",

  24. "pcpn": "0.0",

  25. "pres": "995",

  26. "tmp": "25",

  27. "vis": "4",

  28. "wind_deg": "100",

  29. "wind_dir": "东风",

  30. "wind_sc": "1",

  31. "wind_spd": "4"

  32. }

  33. }]

  34. }

字符串1解析函数

主要是JSON的多层嵌套的解析。

  1. int Parse_HeWeather_Now_Json(void)

  2. {

  3. QJsonParseError err_rpt;

  4. QJsonDocument root_Doc = QJsonDocument::fromJson(he_now_json, &err_rpt);//字符串格式化为JSON


  5. if(err_rpt.error != QJsonParseError::NoError)

  6. {

  7. qDebug() << "JSON格式错误";

  8. return -1;

  9. }

  10. else //JSON格式正确

  11. {

  12. // qDebug() << "JSON格式正确:\n" << root_Doc;


  13. QJsonObject root_Obj = root_Doc.object();

  14. QJsonValue weather_Value = root_Obj.value("HeWeather6"); //HeWeather6键的值,是一个数组

  15. if(weather_Value.isArray()) //可省略

  16. {

  17. QJsonObject weather_Obj = weather_Value.toArray().at(0).toObject(); //HeWeather6数组就含有一个元素0


  18. /* basic键信息 */

  19. QJsonObject basic_Obj = weather_Obj.value("basic").toObject();

  20. QString cid = basic_Obj.value("cid").toString();

  21. QString location = basic_Obj.value("location").toString();

  22. QString parent_city = basic_Obj.value("parent_city").toString();

  23. QString cnty = basic_Obj.value("cnty").toString();

  24. QString lat = basic_Obj.value("lat").toString();

  25. QString lon = basic_Obj.value("lon").toString();

  26. QString basic_info = cid + " " + parent_city + " " + cnty + " " + lat + " " + lon;

  27. qDebug() << basic_info;


  28. /* update键信息 */

  29. QJsonObject update_Obj = weather_Obj.value("update").toObject();

  30. QString loc = "当地时间:" + update_Obj.value("loc").toString(); //当地时间

  31. QString utc = "UTC时间:" + update_Obj.value("utc").toString(); //UTC时间

  32. QString status = "解析状态:" + weather_Obj.value("status").toString(); //"ok"

  33. qDebug() << loc + " " + utc + " " + status;


  34. /* now键信息*/

  35. QJsonObject now_Obj = weather_Obj.value("now").toObject();

  36. QString cond_txt = "白天天气:" + now_Obj.value("cond_txt").toString();

  37. QString hum = "湿度:" + now_Obj.value("hum").toString();

  38. QString tmp = "温度:" + now_Obj.value("tmp").toString();

  39. QString wind_dir = "风向:" + now_Obj.value("wind_dir").toString();

  40. QString wind_sc = "风级:" + now_Obj.value("wind_sc").toString();

  41. qDebug() << cond_txt + " " + hum + " " + tmp + " " + wind_dir + " " + wind_sc;

  42. }

  43. qDebug() << "解析完成!";

  44. }

  45. return 0;

  46. }


示例字符串2:心知天气实时数据

这个字符串和上面那个一样,都是数组元素是JSON对象,对象的值又是一个JSON对象。

  1. {

  2. "results": [{

  3. "location": {

  4. "id": "WX4FBXXFKE4F",

  5. "name": "北京",

  6. "country": "CN",

  7. "path": "北京,北京,中国",

  8. "timezone": "Asia/Shanghai",

  9. "timezone_offset": "+08:00"

  10. },

  11. "now": {

  12. "text": "晴",

  13. "code": "1",

  14. "temperature": "-7"

  15. },

  16. "last_update": "2018-12-06T22:05:00+08:00"

  17. }]

  18. }

字符串2解析函数

  1. int Parse_Seniverse_Now_Json(void)

  2. {

  3. QJsonParseError err_rpt;

  4. QJsonDocument root_Doc = QJsonDocument::fromJson(seniverse_now_json, &err_rpt);//字符串格式化为JSON

  5. if(err_rpt.error != QJsonParseError::NoError)

  6. {

  7. qDebug() << "JSON格式错误";

  8. return -1;

  9. }

  10. else //JSON格式正确

  11. {

  12. // qDebug() << "JSON格式正确:\n" << root_Doc;

  13. QJsonObject root_Obj = root_Doc.object();

  14. QJsonValue result_Value = root_Obj.value("results");

  15. if(result_Value.isArray())

  16. {

  17. QJsonObject result_Obj = result_Value.toArray().at(0).toObject();


  18. QString last_update = result_Obj.value("last_update").toString();

  19. qDebug() << last_update;


  20. /* location键的值 */

  21. QJsonObject location_Obj = result_Obj.value("location").toObject();

  22. QString id = location_Obj.value("id").toString();

  23. QString name = location_Obj.value("name").toString();

  24. QString timezone = location_Obj.value("timezone").toString();

  25. QString path = location_Obj.value("path").toString();

  26. QString loc_str = id + " " + name + " " + timezone + " " + path ;

  27. qDebug() << loc_str;


  28. /* now键 */

  29. QJsonObject now_Obj = result_Obj.value("now").toObject();

  30. QString code = "天气代码: " + now_Obj.value("code").toString();

  31. QString temperature = "当前温度:" + now_Obj.value("temperature").toString();

  32. QString text = "天气:" + now_Obj.value("text").toString();

  33. qDebug() << code << temperature << text;

  34. }

  35. }

  36. return 0;

  37. }

示例字符串3:心知3天天气预报数据

  1. {

  2. "results": [{

  3. "location": {

  4. "id": "WS10730EM8EV",

  5. "name": "深圳",

  6. "country": "CN",

  7. "path": "深圳,深圳,广东,中国",

  8. "timezone": "Asia/Shanghai",

  9. "timezone_offset": "+08:00"

  10. },

  11. "daily": [{

  12. "date": "2018-12-06",

  13. "text_day": "阴",

  14. "code_day": "9",

  15. "text_night": "阴",

  16. "code_night": "9",

  17. "high": "25",

  18. "low": "16",

  19. "precip": "",

  20. "wind_direction": "无持续风向",

  21. "wind_direction_degree": "",

  22. "wind_speed": "10",

  23. "wind_scale": "2"

  24. }, {

  25. "date": "2018-12-07",

  26. "text_day": "阴",

  27. "code_day": "9",

  28. "text_night": "小雨",

  29. "code_night": "13",

  30. "high": "20",

  31. "low": "15",

  32. "precip": "",

  33. "wind_direction": "北",

  34. "wind_direction_degree": "0",

  35. "wind_speed": "15",

  36. "wind_scale": "3"

  37. }, {

  38. "date": "2018-12-08",

  39. "text_day": "小雨",

  40. "code_day": "13",

  41. "text_night": "小雨",

  42. "code_night": "13",

  43. "high": "17",

  44. "low": "12",

  45. "precip": "",

  46. "wind_direction": "东北",

  47. "wind_direction_degree": "45",

  48. "wind_speed": "15",

  49. "wind_scale": "3"

  50. }],

  51. "last_update": "2018-12-06T18:00:00+08:00"

  52. }]

  53. }

字符串3解析函数

  1. int Parse_Seniverse_Forecast_Json(void)

  2. {

  3. QJsonParseError err_rpt;

  4. QJsonDocument root_Doc = QJsonDocument::fromJson(seniverse_forcast_json, &err_rpt);//字符串格式化为JSON

  5. if(err_rpt.error != QJsonParseError::NoError)

  6. {

  7. qDebug() << "JSON格式错误";

  8. return -1;

  9. }

  10. else //JSON格式正确

  11. {

  12. // qDebug() << "JSON格式正确:\n" << root_Doc;

  13. QJsonObject root_Obj = root_Doc.object();

  14. QJsonValue result_Value = root_Obj.value("results");

  15. if(result_Value.isArray())

  16. {

  17. QJsonObject result_Obj = result_Value.toArray().at(0).toObject();


  18. QString last_update = result_Obj.value("last_update").toString();

  19. qDebug() << last_update;

  20. /* location键的值 */

  21. QJsonObject location_Obj = result_Obj.value("location").toObject();

  22. QString id = location_Obj.value("id").toString();

  23. QString name = location_Obj.value("name").toString();

  24. QString timezone = location_Obj.value("timezone").toString();

  25. QString path = location_Obj.value("path").toString();

  26. QString loc_str = id + " " + name + " " + timezone + " " + path ;

  27. qDebug() << loc_str;


  28. /* daily预报天气3天,数组元素3个*/

  29. QJsonValue daily_Vaule = result_Obj.value("daily");

  30. if(daily_Vaule.isArray())

  31. {

  32. for(int idx = 0; idx <= 2; idx++)

  33. {

  34. QJsonObject daily_Obj = daily_Vaule.toArray().at(idx).toObject();

  35. QString date = " 日期:" + daily_Obj.value("date").toString();

  36. QString text_day =" 白天天气:" + daily_Obj.value("text_day").toString();

  37. QString high = " 最高温度:" + daily_Obj.value("high").toString();

  38. QString low = " 最低温度:" + daily_Obj.value("low").toString();

  39. QString wind_direction = " 风向:" + daily_Obj.value("wind_direction").toString();

  40. QString wind_scale = " 风级:" + daily_Obj.value("wind_scale").toString();

  41. qDebug() << date + text_day + high + low + wind_direction + wind_scale;

  42. }

  43. }

  44. }

  45. }

  46. return 0;

  47. }

示例字符串4:空气AQI质量指数

包含10个元素的数组。

  1. {

  2. "status": "0",

  3. "citye": "changchun",

  4. "city": "长春",

  5. "citycode": "101060101",

  6. "aqi": "50",

  7. "data": [{

  8. "add": "长春",

  9. "aqi": "50",

  10. "pm25": "22",

  11. "per": "优",

  12. "lv": "1"

  13. }, {

  14. "add": "食品厂",

  15. "aqi": "54",

  16. "pm25": "18",

  17. "per": "良",

  18. "lv": "2"

  19. }, {

  20. "add": "客车厂",

  21. "aqi": "52",

  22. "pm25": "20",

  23. "per": "良",

  24. "lv": "2"

  25. }, {

  26. "add": "邮电学院",

  27. "aqi": "35",

  28. "pm25": "24",

  29. "per": "优",

  30. "lv": "1"

  31. }, {

  32. "add": "劳动公园",

  33. "aqi": "45",

  34. "pm25": "19",

  35. "per": "优",

  36. "lv": "1"

  37. }, {

  38. "add": "园林处",

  39. "aqi": "45",

  40. "pm25": "21",

  41. "per": "优",

  42. "lv": "1"

  43. }, {

  44. "add": "净月潭",

  45. "aqi": "46",

  46. "pm25": "30",

  47. "per": "优",

  48. "lv": "1"

  49. }, {

  50. "add": "甩湾子",

  51. "aqi": "51",

  52. "pm25": "24",

  53. "per": "良",

  54. "lv": "2"

  55. }, {

  56. "add": "经开区环卫处",

  57. "aqi": "48",

  58. "pm25": "25",

  59. "per": "优",

  60. "lv": "1"

  61. }, {

  62. "add": "高新区管委会",

  63. "aqi": "51",

  64. "pm25": "16",

  65. "per": "良",

  66. "lv": "2"

  67. }, {

  68. "add": "岱山公园",

  69. "aqi": "49",

  70. "pm25": "19",

  71. "per": "优",

  72. "lv": "1"

  73. }]

  74. }

字符串4解析函数

  1. int Parse_AQI_Json(void)

  2. {

  3. QJsonParseError err_rpt;

  4. QJsonDocument root_Doc = QJsonDocument::fromJson(AQI_json, &err_rpt);//字符串格式化为JSON

  5. if(err_rpt.error != QJsonParseError::NoError)

  6. {

  7. qDebug() << "JSON格式错误";

  8. return -1;

  9. }

  10. else //JSON格式正确

  11. {

  12. // qDebug() << "JSON格式正确:\n" << root_Doc;

  13. QJsonObject root_Obj = root_Doc.object();


  14. QString city = root_Obj.value("city").toString();

  15. QString citycode = root_Obj.value("citycode").toString();

  16. QString citye = root_Obj.value("citye").toString();

  17. QString status = root_Obj.value("status").toString();

  18. qDebug() << city + " " + citycode + " " + citye + " " + status;


  19. /* data键 */

  20. QJsonValue data_Vaule = root_Obj.value("data");

  21. if(data_Vaule.isArray())

  22. {

  23. for(int idx = 0; idx <= 10; idx++)

  24. {

  25. QJsonObject data_Obj = data_Vaule.toArray().at(idx).toObject();

  26. QString add = "地址:" + data_Obj.value("add").toString();

  27. QString aqi = " AQI:" + data_Obj.value("aqi").toString();

  28. QString lv = " 空气质量等级:" + data_Obj.value("lv").toString();

  29. QString per = " 空气质量:" + data_Obj.value("per").toString();

  30. QString pm25 = " PM2.5等级:" + data_Obj.value("pm25").toString();

  31. qDebug() << add + aqi + lv + per + pm25;

  32. }

  33. }

  34. }

  35. return 0;

  36. }



示例字符串5:北京标准时间

比较简单一个JSON对象

  1. {

  2. "success": "1",

  3. "result": {

  4. "timestamp": "1542456793",

  5. "datetime_1": "2018-11-17 20:13:13",

  6. "datetime_2": "2018年11月17日 20时13分13秒",

  7. "week_1": "6",

  8. "week_2": "星期六",

  9. "week_3": "周六",

  10. "week_4": "Saturday"

  11. }

  12. }

字符串5解析函数

  1. int Parse_BJTime_Json(void)

  2. {

  3. QJsonParseError err_rpt;

  4. QJsonDocument root_Doc = QJsonDocument::fromJson(bj_time_json, &err_rpt);//字符串格式化为JSON

  5. if(err_rpt.error != QJsonParseError::NoError)

  6. {

  7. qDebug() << "JSON格式错误";

  8. return -1;

  9. }

  10. else //JSON格式正确

  11. {

  12. // qDebug() << "JSON格式正确:\n" << root_Doc;

  13. QJsonObject root_Obj = root_Doc.object();


  14. QString success = root_Obj.value("success").toString();

  15. /* result键 */

  16. QJsonObject result_Obj = root_Obj.value("result").toObject();

  17. QString datetime_1 = result_Obj.value("datetime_1").toString();

  18. QString datetime_2 = result_Obj.value("datetime_2").toString();

  19. QString timestamp = result_Obj.value("timestamp").toString();

  20. QString week_1 = result_Obj.value("week_1").toString();

  21. QString week_2 = result_Obj.value("week_2").toString();

  22. QString week_3 = result_Obj.value("week_3").toString();

  23. QString week_4 = result_Obj.value("week_4").toString();

  24. qDebug() << datetime_1 << datetime_2;

  25. qDebug() << week_1 << week_2 << week_3 << week_4;

  26. }

  27. return 0;

  28. }

示例字符串6:全国城市油价信息

这种格式的字符串也是标准的JSON字符串,[]表示数组,这个数组内包含了5个字符串:

  1. ["北京", "6.78", "7.21", "8.19", "6.45"]

但是这种不是,{}表示对象:

  1. {"北京", "6.78", "7.21", "8.19", "6.45"}

一个数组内包含5个元素,每个元素又是一个数组,每个数组又包含5个字符串,属于数组的嵌套:

  1. {

  2. "status": "0",

  3. "msg": "全国各省份汽柴油价格信息",

  4. "update": "2019-07-21",

  5. "data": [

  6. ["地区", "92号", "95号", "98号", "0号柴油"],

  7. ["北京", "6.78", "7.21", "8.19", "6.45"],

  8. ["上海", "6.74", "7.17", "7.87", "6.39"],

  9. ["江苏", "6.75", "7.18", "8.06", "6.37"],

  10. ["天津", "6.77", "7.15", "8.07", "6.41"]

  11. ],

  12. "About": "wcc",

  13. "Home": "www.wangchaochao.top"

  14. }

字符串6解析函数

  1. //解析数组嵌套的JSON字符串

  2. int Parse_Oil_Price_Json(void)

  3. {

  4. QJsonParseError err_rpt;

  5. QJsonDocument root_Doc = QJsonDocument::fromJson(oil_price_json, &err_rpt);//字符串格式化为JSON

  6. if(err_rpt.error != QJsonParseError::NoError)

  7. {

  8. qDebug() << "JSON格式错误";

  9. return -1;

  10. }

  11. else //JSON格式正确

  12. {

  13. // qDebug() << "JSON格式正确:\n" << root_Doc;

  14. QJsonObject root_Obj = root_Doc.object();


  15. QString msg = root_Obj.value("msg").toString();

  16. QString update = root_Obj.value("update").toString();

  17. QString status = root_Obj.value("status").toString();

  18. QString About = root_Obj.value("About").toString();

  19. QString Home = root_Obj.value("Home").toString();

  20. qDebug() << msg << update << status << About << Home;


  21. /* data键解析 */

  22. QJsonValue data_Value = root_Obj.value("data");

  23. if(data_Value.isArray()) //数组中包含5个数组,每个数组5个字符串元素

  24. {

  25. for(int idx = 0; idx <= 4; idx++)

  26. {

  27. QJsonValue price_Obj = data_Value.toArray().at(idx);

  28. if(price_Obj.isArray())

  29. {

  30. QString str1 = price_Obj.toArray().at(0).toString();// 每个元素是一个字符串

  31. QString str2 = price_Obj.toArray().at(1).toString();

  32. QString str3 = price_Obj.toArray().at(2).toString();

  33. QString str4 = price_Obj.toArray().at(3).toString();

  34. QString str5 = price_Obj.toArray().at(4).toString();

  35. qDebug() << str1 << str2 << str3 << str4 << str5 ;

  36. }

  37. }

  38. }

  39. }

  40. return 0;

  41. }

参考资料

  • JSON官方网站:

http://www.json.org/json-zh.html

总结

JSON解析配合API接口,就可以实现一些有趣的工具了,如全国油价查询工具,全国天气查询,空气质量查询,黄历查询,生活指数等等实用工具的开发。

分享几个免费的API提供平台:

  • K780:

http://www.k780.com/api

  • 天气API:

http://api.help.bj.cn/api/

  • 心知天气:

https://www.seniverse.com/

  • 和风天气:

http://www.heweather.com

  • 聚合数据:

https://www.juhe.cn/

历史精选


我的博客:www.wangchaochao.top

或微信扫码关注我的公众号


由于微信文章不支持超链接,文中出现的软件、程序等文件下载,可以点击"阅读原文",跳转到我的博客文章进行下载。



原创不易,如果觉得我的文章对你有所帮助,可以随手点“好看”分享,你的支持将是我持续更新的动力。

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存