qt 生成json对象与解析json数据
Qt5 中包含了处理 JSON 的类,均以 QJson 开头(例如:QJsonDocument、QJsonArray、QJsonObject),在 QtCore 模块中,不需要额外引入其它模块。
简述
Qt5 中包含了处理 JSON 的类,均以 QJson 开头(例如:QJsonDocument、QJsonArray、QJsonObject),在 QtCore 模块中,不需要额外引入其它模块。
常用的 JSON 库
json.org 中介绍了 JSON 在各种语言中的应用,在 C/C++ 中比较常用的JSON 库主要有以下几个:
-
JsonCpp
JsonCpp 是一个 C++ 用来处理 JSON 数据的开发包。
网址:JsonCpp -
cJSON
cJSON 是一个超轻巧,携带方便,单文件,简单的可以作为 ANSI-C 标准的 JSON 解析器。
网址:cJSON download | SourceForge.net -
QJson
QJson 是一个基于 Qt 的开发包用来将 JSON 数据解析成 QVariant 对象,JSON 的数组将被映射为QVariantList 实例,而其他对象映射为 QVariantMap 实例。
网址:QJson
在此,引进一个变量:QByteArray
QByteArray是Qt中的字节数组类,它提供了一种方便的方式来管理和操作二进制数据;
用于处理二进制数据和字符串之间的转换
使用QByteArray可以将JSON数据从网络上获取并存储在内存中。然后,可以使用QJsonDocument将该数据解析为QJsonObject或QJsonValue。可以使用QJsonObject的方法来访问其中的键值对,或者使用QJsonValue的方法来确定值的类型并提取其值。可以使用QJsonDocument将QJsonObject或QJsonValue转换为JSON格式的QByteArray,以便将其发送到网络或存储在文件中。
//QByteArray类提供一个字节数组
QByteArray buf;
//使用QByteArray可以将JSON数据从网络上获取并存储在内存中
buf = m_tcpSocket->readAll();
// 将QByteArray转换为QJsonDocument
QJsonDocument document = QJsonDocument::fromJson(buf, &error);
// 将QJsonDocument转换为QByteArray
QByteArray buf = document.toJson();
关于 Qt 中对 JSON 的生成与解析,Qt5 以前的版本,可以使用 QJson 库,需要单独下载、编译,才能使用。到了 Qt5,提供了专门的 QJsonDocument 及其相关类来读和写 JSON 文档。
JSON 常用类
QJsonDocument
QJsonDocument 类用于读和写 JSON 文档。
一个 JSON 文档可以使用 QJsonDocument::fromJson() 从基于文本的表示转化为 QJsonDocument, toJson() 则可以反向转化为文本。解析器非常快且高效,并将 JSON 转换为 Qt 使用的二进制表示。
已解析文档的有效性,可以使用 !isNull() 进行查询。
如果要查询一个 JSON 文档是否包含一个数组或一个对象,使用 isArray() 和 isObject()。包含在文档中的数组或对象可以使用 array() 或 object() 检索,然后读取或操作。
也可以使用 fromBinaryData() 或 fromRawData() 从存储的二进制表示创建来 JSON 文档。
// QJsonDocument常用api
1. fromJson(const QByteArray &json):将 JSON 格式的字节数组转换为 QJsonDocument。
2. toJson():将 QJsonDocument 转换为 JSON 格式的字符串。
3. object():返回 QJsonDocument 中的 JSON 对象。
4. array():返回 QJsonDocument 中的 JSON 数组。
5. isEmpty():判断 QJsonDocument 是否为空。
6. isNull():判断 QJsonDocument 是否为 null。
7. isObject():判断 QJsonDocument 是否为 JSON 对象。
8. isArray():判断 QJsonDocument 是否为 JSON 数组。
9. isString():判断 QJsonDocument 是否为 JSON 字符串。
10. isBool():判断 QJsonDocument 是否为 JSON 布尔值。
11. isDouble():判断 QJsonDocument 是否为 JSON 数值。
12. isUndefined():判断 QJsonDocument 是否为 JSON 未定义值。
13. fromJson(const QString &json):将 JSON 格式的字符串转换为 QJsonDocument。
14. fromVariant(const QVariant &variant):将 QVariant 转换为 QJsonDocument。
15. toVariant():将 QJsonDocument 转换为 QVariant。
QJsonArray
QJsonArray 类封装了一个 JSON 数组。
JSON 数组是值的列表。列表可以被操作,通过从数组中插入和删除 QJsonValue 。
一个 QJsonArray 可以和一个 QVariantList 相互转换。可以使用 size() 来查询条目的数量,通过 insert() 在指定索引处插入值,removeAt() 来删除指定索引的值。
QJsonObject
QJsonObject 类封装了一个 JSON 对象。
一个 JSON 对象是一个“key/value 对”列表,key 是独一无二的字符串,value 由一个 QJsonValue 表示。
一个 QJsonObject 可以和一个 QVariantMap 相互转换。可以使用 size() 来查询“key/value 对”的数量,通过 insert() 插入“key/value 对”, remove() 删除指定的 key。
// QJsonObject 的 API:
1. insert():向 QJsonObject 中插入一个键值对
2. remove():从 QJsonObject 中移除一个键值对
3. value():获取 QJsonObject 中某个键的值
4. contains():判断 QJsonObject 中是否包含某个键
5. keys():获取 QJsonObject 中所有键的列表
6. size():获取 QJsonObject 中键值对的数量
7. toVariant():将 QJsonObject 转换为 QVariant 对象
8. fromVariant():将 QVariant 对象转换为 QJsonObject 对象
9. take()是一个函数,用于从QJsonObject中获取并删除指定键的值,返回该值。如果指定键不存在,则返回一个未初始化的QJsonValue对象。该函数的作用类似于从字典中删除一个键值对,并返回该值。
QJsonValue
QJsonValue 类封装了一个值。
JSON 中的值有 6 种基本数据类型:
bool(QJsonValue::Bool)
double(QJsonValue::Double)
string(QJsonValue::String)
array(QJsonValue::Array)
object(QJsonValue::Object)
null(QJsonValue::Null)
// QJsonValue 常用api
1. isNull(): 检查该值是否为 null。
2. isBool(): 检查该值是否为 bool 类型。
3. isDouble(): 检查该值是否为 double 类型。
4. isString(): 检查该值是否为字符串类型。
5. isObject(): 检查该值是否为对象类型。
6. isArray(): 检查该值是否为数组类型。
7. toInt(): 将该值转换为整数类型。
8. toDouble(): 将该值转换为 double 类型。
9. toString(): 将该值转换为字符串类型。
10. toObject(): 将该值转换为对象类型。
11. toArray(): 将该值转换为数组类型。
12. operator[](): 获取数组或对象中指定索引或键的值。
13. keys(): 获取对象类型的所有键。
14. size(): 获取数组或对象类型的元素个数。
一个值可以由任何上述数据类型表示。此外,QJsonValue 有一个特殊的标记来表示未定义的值,可以使用 isUndefined() 查询。值的类型可以通过 type() 或 isBool()、isString() 等访问函数查询。同样地,值可以通过 toBool()、toString() 等函数转化成相应的存储类型。
QJsonParseError
QJsonParseError 类用于在 JSON 解析中报告错误。
枚举 QJsonParseError::ParseError:
该枚举描述 JSON 文档在解析过程中所发生的错误类型。
常量 | 值 | 描述 |
---|---|---|
QJsonParseError::NoError | 0 | 未发生错误 |
QJsonParseError::UnterminatedObject | 1 | 对象不正确地终止以右花括号结束 |
QJsonParseError::MissingNameSeparator | 2 | 分隔不同项的逗号丢失 |
QJsonParseError::UnterminatedArray | 3 | 数组不正确地终止以右中括号结束 |
QJsonParseError::MissingValueSeparator | 4 | 对象中分割 key/value 的冒号丢失 |
QJsonParseError::IllegalValue | 5 | 值是非法的 |
QJsonParseError::TerminationByNumber | 6 | 在解析数字时,输入流结束 |
QJsonParseError::IllegalNumber | 7 | 数字格式不正确 |
QJsonParseError::IllegalEscapeSequence | 8 | 在输入时,发生一个非法转义序列 |
QJsonParseError::IllegalUTF8String | 9 | 在输入时,发生一个非法 UTF8 序列 |
QJsonParseError::UnterminatedString | 10 | 字符串不是以引号结束 |
QJsonParseError::MissingObject | 11 | 一个对象是预期的,但是不能被发现 |
QJsonParseError::DeepNesting | 12 | 对解析器来说,JSON 文档嵌套太深 |
QJsonParseError::DocumentTooLarge | 13 | 对解析器来说,JSON 文档太大 |
QJsonParseError::GarbageAtEnd | 14 | 解析的文档在末尾处包含额外的乱码 |
1.1构造JSON 对象:
生成比较简单,由于是一个对象,只需要用 QJsonObject 即可。
{
"Cross Platform": true,
"From": 1991,
"Name": "Qt"
}
// 构建 JSON 对象
QJsonObject json;
json.insert("Name", "Qt");
json.insert("From", 1991);
json.insert("Cross Platform", true);
// 构建 JSON 文档
QJsonDocument document;
document.setObject(json);
QByteArray byteArray = document.toJson(QJsonDocument::Compact);
QString strJson(byteArray);
qDebug() << strJson;
1.2解析JSON 对象
解析如下:
QJsonParseError jsonError;
QJsonDocument doucment = QJsonDocument::fromJson(byteArray, &jsonError); // 转化为 JSON 文档
if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) { // 解析未发生错误
if (doucment.isObject()) { // JSON 文档为对象
QJsonObject object = doucment.object(); // 转化为对象
if (object.contains("Name")) { // 包含指定的 key
QJsonValue value = object.value("Name"); // 获取指定 key 对应的 value
if (value.isString()) { // 判断 value 是否为字符串
QString strName = value.toString(); // 将 value 转化为字符串
qDebug() << "Name : " << strName;
}
}
if (object.contains("From")) {
QJsonValue value = object.value("From");
if (value.isDouble()) {
int nFrom = value.toVariant().toInt();
qDebug() << "From : " << nFrom;
}
}
if (object.contains("Cross Platform")) {
QJsonValue value = object.value("Cross Platform");
if (value.isBool()) {
bool bCrossPlatform = value.toBool();
qDebug() << "CrossPlatform : " << bCrossPlatform;
}
}
}
}
注意:在转化为 QJsonDocument 后,首先需要根据 QJsonParseError 的值判定是否转化成功,然后在进行相应的转化解析。
2.1构造 JSON 数组:
生成比较简单,由于是一个数组,只需要用 QJsonArray 即可。
[
"Qt",
5.1,
true
]
// 构建 JSON 数组
QJsonArray json;
json.append("Qt");
json.append(5.7);
json.append(true);
// 构建 JSON 文档
QJsonDocument document;
document.setArray(json);
QByteArray byteArray = document.toJson(QJsonDocument::Compact);
QString strJson(byteArray);
qDebug() << strJson;
需要注意的是,和上面不同的是,这里使用的是 QJsonDocument 的 setArray() 函数,因为是数组嘛!
2.2解析 JSON 数组
解析如下:
QJsonParseError jsonError;
QJsonDocument doucment = QJsonDocument::fromJson(byteArray, &jsonError); // 转化为 JSON 文档
if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) { // 解析未发生错误
if (doucment.isArray()) { // JSON 文档为数组
QJsonArray array = doucment.array(); // 转化为数组
int nSize = array.size(); // 获取数组大小
for (int i = 0; i < nSize; ++i) { // 遍历数组
QJsonValue value = array.at(i);
if (value.type() == QJsonValue::String) {
QString strName = value.toString();
qDebug() << strName;
}
if (value.type() == QJsonValue::Double) {
double dVersion = value.toDouble();
qDebug() << dVersion;
}
if (value.type() == QJsonValue::Bool) {
bool bCrossPlatform = value.toBool();
qDebug() << bCrossPlatform;
}
}
}
}
和 JSON 对象类似,在遍历数组时,获取每个 value,首先需要判断 value 的类型(和 is***() 函数类似,这里根据 type() 函数返回的枚举值来判断),然后再进行相应的转换。
3.1构造复杂的 JSON
{
"Company": "Digia",
"From": 1991,
"Name": "Qt",
"Page": {
"Developers": "https://www.qt.io/developers/",
"Download": "https://www.qt.io/download/",
"Home": "https://www.qt.io/"
},
"Version": [
4.8,
5.2,
5.7
]
}
// 构建 Json 数组 - Version
QJsonArray versionArray;
versionArray.append(4.8);
versionArray.append(5.2);
versionArray.append(5.7);
// 构建 Json 对象 - Page
QJsonObject pageObject;
pageObject.insert("Home", "https://www.qt.io/");
pageObject.insert("Download", "https://www.qt.io/download/");
pageObject.insert("Developers", "https://www.qt.io/developers/");
// 构建 Json 对象
QJsonObject json;
json.insert("Name", "Qt");
json.insert("Company", "Digia");
json.insert("From", 1991);
json.insert("Version", QJsonValue(versionArray));
json.insert("Page", QJsonValue(pageObject));
// 构建 Json 文档
QJsonDocument document;
document.setObject(json);
QByteArray byteArray = document.toJson(QJsonDocument::Compact);
QString strJson(byteArray);
qDebug() << strJson;
3.2解析对象+数组json
QJsonParseError jsonError;
QJsonDocument doucment = QJsonDocument::fromJson(byteArray, &jsonError); // 转化为 JSON 文档
if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) { // 解析未发生错误
if (doucment.isObject()) { // JSON 文档为对象
QJsonObject object = doucment.object(); // 转化为对象
if (object.contains("Name")) {
QJsonValue value = object.value("Name");
if (value.isString()) {
QString strName = value.toString();
qDebug() << "Name : " << strName;
}
}
if (object.contains("Company")) {
QJsonValue value = object.value("Company");
if (value.isString()) {
QString strCompany = value.toString();
qDebug() << "Company : " << strCompany;
}
}
if (object.contains("From")) {
QJsonValue value = object.value("From");
if (value.isDouble()) {
int nFrom = value.toVariant().toInt();
qDebug() << "From : " << nFrom;
}
}
if (object.contains("Version")) {
QJsonValue value = object.value("Version");
if (value.isArray()) { // Version 的 value 是数组
QJsonArray array = value.toArray();
int nSize = array.size();
for (int i = 0; i < nSize; ++i) {
QJsonValue value = array.at(i);
if (value.isDouble()) {
double dVersion = value.toDouble();
qDebug() << "Version : " << dVersion;
}
}
}
}
if (object.contains("Page")) {
QJsonValue value = object.value("Page");
if (value.isObject()) { // Page 的 value 是对象
QJsonObject obj = value.toObject();
if (obj.contains("Home")) {
QJsonValue value = obj.value("Home");
if (value.isString()) {
QString strHome = value.toString();
qDebug() << "Home : " << strHome;
}
}
if (obj.contains("Download")) {
QJsonValue value = obj.value("Download");
if (value.isString()) {
QString strDownload = value.toString();
qDebug() << "Download : " << strDownload;
}
}
if (obj.contains("Developers")) {
QJsonValue value = obj.value("Developers");
if (value.isString()) {
QString strDevelopers = value.toString();
qDebug() << "Developers : " << strDevelopers;
}
}
}
}
}
}
建议在处理的过程中启用严格模式,例如:先通过 QJsonParseError::NoError 判断转化 JSON 文档无误,再进行解析。在解析过程中,先判断 QJsonValue 是否为对应的类型如 isObject(),再通过 toObject() 转化。
更多推荐
所有评论(0)