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類使用隱式共享,無需擔心深拷貝性能問題