关于上面的描述可以精简为一句话:Json 是一种数据格式,和语言无关,在什么语言中都可以使用 Json。基于这种通用的数据格式,一般处理两方面的任务:
组织数据(数据序列化),用于数据的网络传输
组织数据(数据序列化),写磁盘文件实现数据的持久化存储(一般以.json 作为文件后缀)
Json 中主要有两种数据格式:Json 数组和 Json 对象,并且这两种格式可以交叉嵌套使用,下面依次介绍下这两种数据格式:
2.JSON 数组
3.JSON 对象
键值:必须是字符串;
value:整形、浮点、字符串、布尔、json数组、JSON对象、空置-null
//注意:最后一个元素的后面是不可以加逗号的;
//注意:文件以 .json 为后缀,这样有助于第一时间确认这个文件的数据格式为 JSON 格式;
//注意:一个文件同时只能有一个大的格式,要么是JSON对象{} 要么是JSON数组[] 意思也就是保证根节点只有一个;
4.QT中JSON操作;
QJsonDocument
1.把JSON数组、JSON对象转换成 字符串;---->JSON数据组织;
2.把字符串 转换成JSON数组、JSON对象;---->JSON数据解析;
QJsonArray
1. 在C++的数组中,一个数组只能存放一种数据类型,这里QT提供了一种方式,对不同的数据类型再次包装
把他们包装成统一的一种类型;这样在对数组操作的时候,只需要对一种类型进行操作;
QJsonObject
1.封装了JSON对象;
2. 类似于 key值 和 value值;key值 是统一的字符串类型;
QJsonValue
3.对JSON的value值进行统一的包装,然后存放;可以查看类QJsonValue的构造函数;
发现可以包含各种类型的value值;QJsonValue类就是对数据进行包;
数据封住之后,如何知道当前封装的是哪种数据类型呢,可以利用is方法判断数据类型;
识别出哪种数据类型之后,再把数据使用 to方法 转换为具体的数据类型,
QJsonObject类的使用:
通过这个类可以想JSON里面添加若干个键值对;
1.构造一个空的JSON对象;
QJsonObject::QJsonObject();
2. 将键值对添加到空对象中;
iterator QJsonObject::insert(const Qstring &key, const QJsonValue &value);
3.获取对象中键值对个数;
int QJsonObject::count() const;
int QJsonObject::size() const;
int QJsonObject::length() const;
4.通过key值 得到 value值;
QJsonValue QJsonObject::value(const QString &key) const;
//注释:方法接收一个 字符串形式的key值,返回一个QJsonValue类型的对象,对象中保存数据,之后再类型判断-->类型转换就可以得到原始类型的数据;
QJsonValue QJsonObject::value(QLation1String key) const;
QJsonValue QJsonObject::operator[](const QString &key) const;
QJsonValue QJsonObject::operator[](QLatin1String key) const;
5. 删除JSON中的数据;
void QJsonObject::remove(const QString &key);
QJsonValue QJsonObject::take(const QString &key); //返回key对应的value的返回值(再次访问value就没有了);
6.通过key进行查找;
iterator QJsonObject::find(const QString &key); //返回当前元素的迭代器,通过迭代器查找元素;
bool QjsonObject::contains(const QString &key) const; //检查键值对是否存在,存在return ture;
7. 遍历;
1、使用相关迭代器函数;
2、使用[] 的方式遍历,类似于遍历数组,[]中是键值; //前面有[]的重载;
3、先得到对象中所有的键值,再遍历键值列表,通过key得到value值;
QstringList QJsonObject::keys() const;
//注释:调用JSON对象的keys() 方法,返回一个QstringList的字符串集合(是一个字符串数组),字符串中包含所有的key值,然后
对字符串数组进行遍历,依次取出key值,再取出value值;
QJsonArray类的使用
//
1. 创建空的JSON数组;
1. QJsonArray::QJsonArray();
2.添加数据;
1、void QJsonArray::append(const QJsonValue &value); //添加到尾部;
2、void QJsonArray::insert(int i, const QJsonValue &value); //插到 i 之前的位置;
3、iterator QJsonArray::insert(iterator before, const QJsonValue &value);
4、void QJsonArray::prepend(const QJsonValue &value); //添加到数组头部
5、void QJsonArray::push_back(const QJsonValue &value); //添加到数组尾部
6、void QJsonArray::push_front(const QJsonValue &value) //添加到数组头部;
3.计算数组元素的个数;
1、int QJsonArray::count() const;
2、int QJsonArray::size() const;
4.从数组中取出某一个元素的值
1、QJsonValue QJsonArray::at(int i) const;
2、QJsonValue QJsonArray::first() const; //头部元素,得到数组的第一个元素[0]
3、QJsonValue QJsonArray::last() const; //尾部元素
4、QJsonValueRef QJsonArray::operator[](int i);
// QJsonValueRef 返回的是对应的元素位置的引用,而first 和 last 返回的是对应的元素的位置的拷贝;
//注释:取出JSON数组中的value值以后,和QJsonObject对象一样,需要对获取的value值进行判断,再用to方法对value值进行数据转换;
意思就是说QJsonArray取出来的元素也要数据类型判定和数据类型转换,这两部之后才能得到最原始的数据类型;
5.删除数组中的某一个元素
1、iterator QJsonArray::erase(iterator it); //使用迭代器删除;
2、void QJsonArray::pop_back(); //删除尾部
3、void QJsonArray::pop_front(); //删除头部
4、void QJsonArray::removeAt(int i); //删除 i 位置的元素
5、void QJsonArray::removeFirst(); //删除头部
6、void QJsonArray::removeLast(); //删除尾部
7、QJsonValue QJsonArray::takeAt(int i) //删除 i 位置的原始,并返回删除元素的值;
6.JSON数组的遍历,常用的方式有两种
1.使用迭代器遍历,(和使用迭代器遍历STL容器一样)
2.使用数组的方式遍历; //JSON数组中元素是从0开始的,用count 和 size方法求出数组大小,然后用for循环遍历;
//注释:通过insert方法向 QJsonObject 里面添加数据的时候,insert 插入的顺序和最终的顺序可能是不一样的,
因为数据添加到JSON对象内部之后会再次根据key值排序,
而 QJsonArray 中添加的顺序和遍历的顺序(最终的顺序)是绝对一致的;
QJsonDocument类的使用
1.先看一下QJsonDocument 的构造函数;
1. 第一个是移动构造,引用一个引用;
2.第二个是拷贝构造,
3.4. 第三个、第四个 通过接收 QJsonArray 和 QJsonObject的对象,返回一个QJsonDocument的对象,其实还是对数据的封装;
5. QJsonDocument() 通过这个构造函数得到一个空对象;
2. QJsonDocument 对象的初始化和重置
//调用setArray、setObject方法
void setArray(const QJsonArray &array)
void setObject(const QJsonObject &object)
//注释:通过这两个set方法把 JSON数组对象 和 JSON Object对象 传递给 QJsonDocument()创建的空对象;
就完成了 类QJsonArray 和 类QJsonObject 到 类QJsonDocument 的转换;
//也可以用这两个方法传递给QJsonDocument(const QJsonArray &other)
和 QJsonDocument(const QJsonObject &other)创建的有数据的对象进行重置;
3.void swap(QJsonDocumen &other) //数据交换
4. QJsonDocument 对象封装后的数据 如何得到原始数据呢;
1.首先进行数据类型判断;
1、bool isArray() const;
2、bool isEmpty() const;
2.完成数据类型转换;
1.QJsonArray array() const;
2.QJsonObject object() const;
5.判断QJsonDocument 对象里面没有数据、判断JSON文档里面存储的是否为 空置null
1.boot isEmpty() const;
2.bool isNull() const;
6.对象到字符串的转换?
1. QByteArray toJson() const; //转换成文本格式的字符串;
2. QByteArray toJson(QJsonDocunment::JsonFormat format) const;
3.QByteArray QJsonDocument::toBinaryDate() const; //二进制格式的json字符串;
//QByteArray 在QT里面就是字符串类型;
// JSON格式的字符串 《==》 QJsonDocument 类的对象,
6.如何把字符串转换成对象?
QJsonDocument fromJson(const QByteArray &json, QJsonParaseError &error = nullptr)
// QByteArray 就是字符串类型;返回一个被实例化的 QJsonDocument 对象,有了这个对象就可以转换为 QJsonObject对象或者 QJsonArray 数组;进而完成字符串的解析,也就是JSON文件的解析;
通过JSON对数据序列化;
// test.json
{
"Name":"Ace",
"Sex":"man",
"Age":20,
"Family":{
"Father":"Gol·D·Roger",
"Mother":"Portgas·D·Rouge",
"Brother":["Sabo", "Monkey D. Luffy"]
},
"IsAlive":false,
"Comment":"yyds"
}
void MainWindow::ReadJsonFile()
{
}
void MainWindow::WriteJsonFile()
{
QJsonObject obj;
obj.insert("Name", "Ace"); //这里有隐式类型转换,把"Ace" 实例化为 QJsonValue 的对象;
obj.insert("Sex", "man");
obj.insert("Age", 20);
QJsonObject obj_family();
obj_family.insert("Father", "Gol·D·Roger");
obj_family.insert("Mother", "Oirtgas·D·Rouge");
QJsonArray array;
array.insert(0, "Sabo"); //虽然 QJsonArray 的 insert 方法接收的是 QJsonValue 对象的引用,但是这里会把字符串 "Sabo" 进行隐式类型转换成 QJsonValue 对象;
array.insert(1, "Monkey D. Luffy");
obj_family("Brother", array);
obj.insert("family", obj_family);
obj.insert("isAlive", false);
obj.insert("Comment", "yyds");
//以上数据转换完毕,接下来就是将JSON对象转换为 JSON文档对象;
QJsonDocument doc(obj);
//得到JSON文档对象,调用 toJson 方法转换成文本格式的字符串;
QByteArray json = doc.toJson(); // toBinaryDate 方法转换成 二进制格式的字符串;
//把转换得到的JSON文本格式字符串写到磁盘文件中;
QFile file("D:\\ace.json")
file.open(QFile::WriteOnly);
file.write(json);
file.close();
//以上就完成了写JSON文件的操作;
}
JSON格式的字符串 反序列化
JSON格式的字符串有可能是网络文件传输得到的,也可能是读磁盘文件得到的;现在要把JSON格式字符串加载到JSON
对象QJsonObject 或者 JSON数组QJsonArray里面;即:
字符串 ====》 QJsonObject 或者 QJsonArray
步骤:
1.得到的JSON格式字符串通过 QJsonDocument 类的静态函数转换为 QJsonDocument 对象;
1.QJsonDocument QJsonDocument::fromBinaryData(const QByteArray &data, DataValidatior ...) //处理的是二进制格式的JSON字符串;
2.QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error = nullptr) //处理的是文本格式的JSON字符串;
//注释:这两个函数都返回一个文档对象
2.将文档对象 转换为 Json数组/对象;
1.判断文档对象中存储的是 json数组 还是 json对象
bool QJsonDocument::isArray() const;
bool QJsonDocument::isObject() const;
2.把文档QJsonDocument对象 转换为 json数组 或者 json对象
QJsonArray QJsonDocument::array() const; //转换为JSON数组;
QJsonObject QJsonDocument::object() const; //转换为json对象;
3.通过调用 QJsonArray 和 QJsonObject 的API完成对json数据的读取;
代码实现: