-
1、什么是JSON?
JSON(JavaScript Object Notation)是一种轻量级的、通用的数据格式,可供各式各样的客户端和服务端进行通信;
JSON本质上是一种特殊格式的字符串
它有以下特点:
- 便于阅读书写
除了JSON格式,还有一种数据传输格式XML(Qt的ui文件就是XML格式);相对于XML,JSON更加利于阅读
- 独立于编程语言
几乎在所有的编程语言和开发环境中,都有解析和生成JSON字符串的库
# C
Jansson,cJSON
# C++
jsonCpp,JSON for Modern C++
# Java
json-lib,org-json
# Android
Gson FastJson
# Qt
QJsonXxx
- 网络传输的标准格式
基于以上特点,JSON成为了网络传输使用率最高的数据格式
2、JSON的两种数据格式
JSON有两种数据格式
- JSON对象
- JSON数组
规则:被大括号包裹的是JSON对象;被中括号包裹的是JSON数组
2.1 JSON数组
JSON数组格式
[元素1,元素2,元素3,...,元素n]
此处的元素可以是不同的数据类型,包括:整形、浮点、字符串、布尔、JSON数组、JSON对象、空值
[ 1,2.5,“hello”,true,null ]
JSON数组嵌套
[
[ 1,2,3 ],
[ "hello","my","baby" ],
[ 1,2.5,“hello”,true,null ]
]
JSON数组嵌套对象
[
{
"name" : "Tom",
"age" : 18
}
{
"name" : "Jim",
"age" : 19
}
]
2.2 JSON对象
JSON对象格式:
{
"key1" : value1,
"key2" : value2,
"key3" : value3
}
键key是标准的字符串类型,值value可以是:整形、浮点、字符串、布尔、JSON数组、JSON对象、空值
{
"name": "China",
"info": {
"capital": "beijing ",
"asian": true,
"founded": 1949
},
"provinces": [{
"name": "shandong ",
"capital": "jinan"
},
{
"name": "guangdong ",
"capital": "guangzhou"
}
]
}
2.3 JSON的在线解析
3、Qt中使用JSON
3.1JSON相关的类
- QJsonObject
- QJsonArray
- QJsonValue
- QJsonDocument
(1)QJsonObject
QJsonObject封装了JSON中的对象,可以存储多个键值对。
其中键为字符串类型,值为QJsonValue类型
- 创建一个QJsonObject对象
QJsonObject::QJsonObject();
- 将键值添加到QJsonObject对象中
QJsonObject::iterator insert(const QString &key,const QJsonValue &value);
- 获取QJsonObject对象中的键值对个数
int QJsonObject::count() const;
int QJsonObject::size() const;
int QJsonObject::length() const;
- 通过key获得value的值
QJsonValue QJsonObject::value(const QString &key) const;
QJsonValue QJsonObject::operator[](const QString &key) const;
- 检查key是否存在
iterator QJsonObject::find(const QString &key);
boll QJsonObject::contains(const QString &key) const;
- 遍历key
QStringList QJsonObject::keys() const;
(2)QJsonArray
- 创建一个QJsonArray
QJsonArray::QJsonArray();
- 添加数组元素
//添加到头部和尾部
void QJsonArray::append(const QJsonValue &value);
void QJsonArray::prepend(const QJsonValue &value);
//插入到i的位置之前
void QJsonArray::insert(int i,const QJsonValue &value);
//添加到头部和尾部
void QJsonArray::push_front(const QJsonValue &value);
void QJsonArray::push_back(const QJsonValue &value);
- 获取QJsonArray元素个数
int QJsonArray::count() const;
int QJsonArray::size() const;
- 获取元素的值
//获取头部和尾部的值
QJsonValue QJsonArray::first() const;
QJsonValue QJsonArray::last() const;
//获取指定位置的值
QJsonValue QJsonArray::at(int i) const;
QJsonValueRef QJsonArray::operator[](int i);
- 删除元素
//删除头部和尾部
void QJsonArray::pop_front(;
void QJsonArray::pop_back();
void QJsonArray::removeFirst();
void QJsonArray::removeLast();
//删除指定位置
void QJsonArray::removeAt(int i);
QJsonValue QJsonArray::takeAt(int i);
(3)QJsonValue
封装了6种数据类型
# 布尔
QJsonValue::Bool
# 浮点类型(包括整形)
QJsonValue::Double
# 字符串类型
QJsonValue::String
# Json数组类型
QJsonValue::Array
# Json对象类型
QJsonValue::Object
# 空值类型
QJsonValue::Null
通过以下方式来构造QJsonValue对象
字符串
QJsonValue(const char *s);
QJsonValue(QLatinlString s);
QJsonValue(const QString &s);
整形or浮点型
QJsonValue(qint64 v);
QJsonValue(int v);
QJsonValue(double v);
布尔
QJsonValue(bool b);
Json对象
QJsonValue(const QJsonObject &o);
Json数组
QJsonValue(const QJsonArray &a);
空值类型
QJsonValue(QJsonValue::Type type = Null);
如果已经得到了QJsonValue如何判断内部封装的是什么类型的数据?
bool isString() const;
bool isDouble() const;
bool isBool() const;
bool isObject() const;
bool isArray() const;
bool isUndefined() const;
bool isNull() const;
通过以上判断函数以后,如果有需求可以将其转换为对应的基础数据类型,对应的API函数如下:
转换为字符串
Qstring toString() const;
Qstring toString(const QString &defaultValue) const;
转换为浮点
double toDouble(double defaultValue = 0) const;
转换为整型
int toInt(int defaultValue = 0) const
转换为布尔
bool toBoll(bool defaultValue = false) const;
转换为Json对象
QJsonObject toObject(const QJsonObject &defaultValue) const;
QJsonObject toObject() const;
转换为Json数组
QJsonArray toArray(const QJsonArray &defaultValue) const;
QJsonArray toArray() const;
(4)QJsonDocument
它封装了一个完整的JSON文档
它可以从UTF-8编码的基于文本表示,以及Qt本身的二进制格式读取和写入文档
QJsonObject和QJsonArray这两个是无法直接转换为字符串类型的,需要通过QJsonDocument类来完成二者的转换
- QJsonObject和QJsonArray => 字符串
1、创建QJsonDocument对象
QJsonDocument::QJsonDocument(const QJsonObject &object);
QJsonDocument::QJsonDocument(const QJsonArray &array);
2、将QJsonDocument对象数据序列化
QByteArray QJsonDocment::toBinaryData() const; //二进制格式的Json字符串
QByteArray QJsonDocment::toJson(JsonFormat format = Indented) const; //文本格式
3、使用得到的字符串进行数据传输或者保存到文件
- 字符串 => QJsonObject和QJsonArray
1、将Json字符串 => QJsonDocument对象
[static]QJsonDocument QJsonDocument::fromBinaryData(const QByteArray &data, Datavalidation validation = Validate):
[static] QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR);2、将文档对象转换为json数组/对象
2.1判断文档中存储的数据是JSON数组还是对象
bool QJsonDocument::isArray() const;
bool QJsonDocument::isObject() const;
2.2转换为JSON数组或对象
QJsonObject QJsonDocument::array() const;
QJsonArray QJsonDocument::object() const;
3、调用QJsonArray/QJsonObject类提供的API获取存储在里面的数据
4、JSON实战
4.1 构建JSON字符串
实现效果
{
"name": "China",
"info": {
"capital": "beijing ",
"asian": true,
"founded": 1949
},
"provinces": [{
"name": "shandong ",
"capital": "jinan"
},
{
"name": "guangdong ",
"capital": "guangzhou"
}
]
}
#include <QCoreApplication>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QFile>
#include <QDebug>
void writeJson() {
QJsonObject rootObj;
//1.插入name字段
rootObj.insert("name", "China");
//2 插入info字段
QJsonObject infoObj;
infoObj.insert("capital", "beijing");
infoObj.insert("asian", true);
infoObj.insert("founded", 1949);
rootObj.insert("info", infoObj);
//3 插入provinces字段
QJsonArray provinceArr;
QJsonObject SdObj;
QJsonObject GdObj;
SdObj.insert("name", "shandong");
SdObj.insert("capital", "jinan");
GdObj.insert("name", "guangdong");
GdObj.insert("capital", "guangzhou");
provinceArr.append(SdObj);
provinceArr.prepend(GdObj);
rootObj.insert("province", provinceArr);
//4 将rootObj转化为json字符串
QJsonDocument doc(rootObj);
QByteArray json = doc.toJson();
//5 打印输出
qDebug() << QString(json).toUtf8().data();
//6 将json字符串写入到文件
QFile file("d:\\QtTest\\china.json");
file.open(QFile::WriteOnly);
file.write(json);
file.close();
//文件可以使用NotePad++打开
}
int main(int argc, char* argv[])
{
QCoreApplication a(argc, argv);
writeJson();
return a.exec();
}
小插曲,配置VS大法配置Qt环境
4.2解析JSON字符串
#include <QCoreApplication>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QFile>
#include <QDebug>
void fromJson() {
//1.读取文件
QFile file("d:\\QtTest\\china.json");
file.open(QFile::ReadOnly);
QByteArray json = file.readAll();
file.close();
QJsonDocument doc = QJsonDocument::fromJson(json);
if (!doc.isObject()) {
qDebug() << "Not an object!";
return;
}
QJsonObject obj = doc.object();
QStringList keys = obj.keys();
for (int i = 0; i < keys.size(); i++) {
//获取key-value
QString key = keys[i];
QJsonValue value = obj.value(key);
if (value.isBool()) {
//打印输出
qDebug() << key << ":" << value.toBool();
}
else if (value.isString()) {
//打印输出
qDebug() << key << ":" << value.toString();
}
else if (value.isDouble()) {
//
qDebug() << key << ":" << value.toInt();
}
else if (value.isObject()) {
qDebug() << key << ":";
QJsonObject infoObj = value.toObject();
QString capital = infoObj["capital"].toString();
bool asian = infoObj["asian"].toBool();
int founded = infoObj["founded"].toInt();
qDebug() << " " << "capital" << ":" << capital;
qDebug() << " " << "asian" << ":" << asian;
qDebug() << " " << "founded" << ":" << founded;
}
else if (value.isArray()) {
QJsonArray provinceArray = value.toArray();
qDebug() << key << ":";
for (int i = 0; i < provinceArray.size(); i++) {
QJsonObject provinceObj = provinceArray[i].toObject();
QString name = provinceObj["name"].toString();
QString capital = provinceObj["capital"].toString();
qDebug() << " " << "name" << ":" << name << ", capital" << ":" << capital;
}
}
}
}
int main(int argc, char* argv[])
{
QCoreApplication a(argc, argv);
fromJson();
return a.exec();
}