Qt中解析JSON文件
在Qt中解析JSON字符串主要有两种方式:使用QJsonDocument
类或使用QJsonDocument
结合QVariant
。以下是详细的解析方法:
使用QJsonDocument(推荐)
这种方式的主要相关类如下:
QJsonDocument: QJsonDocument
是 Qt 中处理 JSON 数据的核心类,它提供了在内存中读写 JSON 文档的功能。
主要功能
- 解析 JSON:从 UTF-8 编码的文本创建 JSON 文档
- 生成 JSON:将内存中的 JSON 数据转换为字符串或二进制格式
- 数据访问:提供对 JSON 对象和数组的访问接口
- 格式转换:支持紧凑和缩进两种输出格式
QJsonObject:QJsonObject
是 Qt 中用于表示 JSON 对象的类,它存储键值对集合,其中键是字符串,值可以是各种 JSON 类型。
主要特性
- 键值对存储:存储
QString
作为键,QJsonValue
作为值 - 无序集合:键的顺序不保证与插入顺序一致
- 隐式共享:使用写时复制技术,拷贝开销小
- 类型安全:提供多种类型检查和转换方法
QJsonValue:
QJsonValue
是 Qt 中表示 JSON 值的类,它可以存储 JSON 标准支持的所有数据类型。它是 Qt JSON 系统的核心基础类。
主要特性
- 多类型存储:可以存储 JSON 支持的所有数据类型
- 值语义:拷贝和赋值操作是高效的(隐式共享)
- 类型安全:提供严格的类型检查和转换方法
- 空值和未定义值:支持 JSON null 和未定义值
支持的数据类型
QJsonValue
可以存储以下类型的值:
类型 | 描述 | 对应的 Qt 类型 |
---|---|---|
Null | JSON null 值 | QJsonValue::Null |
Bool | 布尔值 | bool |
Double | 双精度浮点数 | double |
String | 字符串 | QString |
Array | JSON 数组 | QJsonArray |
Object | JSON 对象 | QJsonObject |
Undefined | 未定义值(无效值) | QJsonValue::Undefined |
QJsonArray:
QJsonArray
是 Qt 中用于表示 JSON 数组的类,它存储有序的 QJsonValue
集合。JSON 数组是值的有序列表,可以包含不同类型的元素。
主要特性
- 有序集合:元素保持插入顺序
- 混合类型:可以存储不同类型的值
- 隐式共享:使用写时复制技术,拷贝开销小
- 动态大小:支持动态添加和删除元素
- 索引访问:支持通过索引随机访问元素
下面我们就用进行简单的实战解析。
一、解析简单Json对象
#include <QCoreApplication>
#include<QJsonDocument>
#include<QJsonObject>
#include<QJsonValue>
#include<QJsonArray>void PraseJson()
{QString strJson = R"({"name":"张三","age":30,"isStudent":false})";QJsonDocument doc = QJsonDocument::fromJson(strJson.toUtf8());if(doc.isNull() || !doc.isObject()){qDebug() << "Json解析失败";return;}QJsonObject obj = doc.object();QString strName = obj["name"].toString();int nAge = obj["age"].toInt();bool bStudent = obj["isStudent"].toBool();qDebug() << "名字:" << strName;qDebug() << "年龄:" << nAge;qDebug() << "是否学生:" << bStudent;}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// Set up code that uses the Qt event loop here.// Call a.quit() or a.exit() to quit the application.// A not very useful example would be including// #include <QTimer>// near the top of the file and calling// QTimer::singleShot(5000, &a, &QCoreApplication::quit);// which quits the application after 5 seconds.// If you do not need a running Qt event loop, remove the call// to a.exec() or use the Non-Qt Plain C++ Application template.PraseJson();return a.exec();
}
代码运行结果:
二、解析嵌套Json对象
void PraseJson2()
{QString strJson = R"({"person":{"name":"李四","address":{"city":"北京","street":"长安街"}},"hobbies":["读书","音乐","运动"]})";QJsonDocument doc = QJsonDocument::fromJson(strJson.toUtf8());if(doc.isNull() || !doc.isObject()){qDebug() << "Json解析失败";return;}QJsonObject rootObj = doc.object();QJsonObject personObj = rootObj["person"].toObject();QJsonObject addressObj = personObj["address"].toObject();QString strName = personObj["name"].toString();qDebug() << "名字:" << strName;QString strCity = addressObj["city"].toString();qDebug() << "城市" << strCity;QString strStreet = addressObj["street"].toString();qDebug() << "街道:" << strStreet;QJsonArray arr = rootObj["hobbies"].toArray();qDebug() << "爱好:";for (const QJsonValue& value: arr){qDebug() << value.toString();}}
代码运行结果:
三、解析Json数组
void PraseJson3()
{QString strJson = R"([{"name":"王五","age":30},{"name":"赵六","age":35},{"name":"张三","age":20}])";QJsonDocument doc = QJsonDocument::fromJson(strJson.toUtf8());if(doc.isNull()){qDebug() << "Json解析失败";return;}if(doc.isArray()){QJsonArray arr = doc.array();for(const QJsonValue& value:arr){QJsonObject obj = value.toObject();qDebug() << "名字:"<< obj["name"].toString() << ",年龄:" << obj["age"].toInt();}}
}
代码运行结果:
四、错误处理
void parseJsonWithErrorHandling() {QString jsonString = R"({"invalid": json})"; // 无效的JSONQJsonParseError error;QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8(), &error);if (error.error != QJsonParseError::NoError) {qDebug() << "JSON解析错误:" << error.errorString();return;}if (doc.isNull()) {qDebug() << "文档为空";return;}// 安全地获取值QJsonObject obj = doc.object();QString value = obj.value("key").toString("默认值"); // 如果key不存在,返回默认值// 检查值类型if (obj.contains("key") && obj["key"].isString()) {// 安全处理}
}
五、构建Json对象
void createJson() {QJsonObject person;person["name"] = "张三";person["age"] = 30;QJsonArray hobbies;hobbies.append("读书");hobbies.append("游泳");hobbies.append("编程");person["hobbies"] = hobbies;QJsonObject address;address["city"] = "上海";address["street"] = "南京路";person["address"] = address;QJsonDocument doc(person);QString jsonString = doc.toJson(QJsonDocument::Indented);qDebug() << "生成的JSON:";qDebug() << jsonString;
}
代码运行结果:
注意事项
- 编码问题: 确保JSON字符串使用UTF-8编码
- 错误处理: 总是检查解析是否成功
- 类型安全: 在访问值之前检查其类型
- 内存管理: Qt的JSON类使用隐式共享,无需担心深拷贝性能问题
常用方法
QJsonDocument::fromJson()
- 从字符串创建文档QJsonObject::value()
- 安全获取值(可指定默认值)QJsonValue::toInt()
,toString()
,toBool()
- 类型转换QJsonObject::contains()
- 检查键是否存在QJsonValue::isObject()
,isArray()
,isString()
- 检查值类型
: Qt的JSON类使用隐式共享,无需担心深拷贝性能问题