0、說明
QJsonDocument類提供了read/write JSON文檔的方法。
用QJsonDocument::fromJson()方法,可以從將一個JSON文件(或者QByteArray數據)轉換為QJsonDocument,用QJsonDocument::toJson()則能起到相反的用法。在此過程中的語法解析是很高效的,並且可以將JSON轉換為Qt使用的二進制數據。
可以用 !isNull()來知曉被解析文檔的合法性;用isArray()、isObject()來檢查這個Doc是否包含一個Array或Object。如果要提取這些Array與Object,可以通過調用array()、object()來實現,之后就能對Array、Object進行相關操作。
一個Doc也可以從一個二進制數據中提取,使用fromBinaryData()、fromRawData()。
1、模塊和加載項
Header: | #include <QJsonDocument> |
qmake: | QT += core |
Since: | Qt 5.0 |
2、構造
QJsonDocument(QJsonDocument other) | 可以從QJsonDocument、QJsonArray、QJsonObject中構造 |
QJsonDocument(QJsonArray array) | |
QJsonDocument(QJsonObject object) | |
QJsonDocument() | 構造空QJsonDocument |
3、靜態字段
類型 |
字段 |
可用數據 |
說明 |
enum | DataValidation | { Validate, BypassValidation } | 該字段告訴QJsonDocument要轉化的二進制數據是否合法,即是否可以用fromBinaryData() or fromRawData()來把二進制數據轉化為QJsonDocument |
enum | JsonFormat | { Indented, Compact } | 該字段定義了由QJsonDocument產生的JSON的格式(用於toJson()方法參數) |
JsonFormat
Constant | Value | Description |
---|---|---|
QJsonDocument::Indented |
0 |
Defines human readable output as follows: {
"Array": [ true, 999, "string" ], "Key": "Value", "null": null } |
QJsonDocument::Compact |
1 |
Defines a compact output as follows: {"Array":[true,999,"string"],"Key":"Value","null":null} |
4、靜態方法
返回值類型 |
方法 |
說明 |
QJsonDocument | fromJson(QByteArray json, QJsonParseError *error = nullptr) | 從一個QByteArray中進行解析,提取QJsonDocument。 失敗時,返回null,且第二個參數中會包含更多細節信息。 |
QJsonDocument | fromVariant(QVariant variant) | 從一個QVariant構造一個QJsonDocument。 如果該QVariant包含除QVariantMap, QVariantHash, QVariantList or QStringList以外的類型,返回的document將是非法的 |
5、實例方法
返回值類型 |
方法 |
說明 |
QJsonDocument & bool bool QJsonValue QJsonValue |
operator=(QJsonDocument other) operator!=(const QJsonDocument &other) operator==(const QJsonDocument &other) operator[](QString key) operator[](int i) |
賦值 不相等判斷 相等判斷 取doc[key]對應的QJsonValue,等同於調用object().value(key)。當isObject()返回false時,該方法返回的Object是Undefined類型 用doc[i]的方式訪問QJsonArray中的值 |
QJsonArray | array() | 返回該Doc對應的QJsonArray。 如果包含Object時返回空Array |
bool | isArray() isEmpty() isNull() isObject() |
當Doc包含一個array時返回true 當Doc不含任何數據時返回true 當Doc為null時返回true 當Doc包含一個Object時返回true |
QJsonObject | object() | 返回Doc中包含的QJsonObject 如果包含一個Array返回空Object |
void | setArray(QJsonArray array) setObject(QJsonObject object) |
設置array為該Doc的內容 設置object為該Doc的內容 |
void | swap(QJsonDocument &other) | 交換兩個OJsonDocument的內容 |
QByteArray | toJson() toJson(QJsonDocument::JsonFormat format) |
將QJsonDocument轉化為indented格式,UTF-8編碼的JSON文件 將QJsonDocument轉化為UTF-8編碼,指定格式的JSON文件 |
QVariant | toVariant() | 返回該QJsonDocument對應的QVariant。 當Doc為QJsonArray,返回QVariantList 當Doc為QVariantMap,返回QJsonObject |
6、應用
1)從一個QJsonObject格式的QByteArray中,讀取某個字段的數據(該數據是一個List),存入某個自定義類中:QByteArray → QJsonDocument → QJsonArray → class
有一個QByteArray,類似下邊這種格式:
{"status":0,"result":[{"x":20.0,"y":120.0},{"x":30.0,"y":121.0}]}
要求
讀取result字段值,得到一個QJsonArray,該array的每一項都是一個QJsonValue,提取每一項的x、y字段,存入一個QJsonObject對象中,再把所有這些QJsonObject,加上一個ID項,存入一個QJsonArray中:
①QByteArray → QJsonDocument:QJsonDocument::fromJson( QByteArray )
QJsonDocument doc = QJsonDocument::fromJson(data);//data就是上文的QByteArray
②QJsonDocument → QJsonArray(result字段對應的值是一個List):QJsonDocument.[Key].toArray()
QJsonArray resultArray = doc["result"].toArray();
③提取Array中的每一項中的x、y,存入相同數量的QJsonObject中,並為每個QJsonObject都添加一個ID字段;這些QJsonObject在生成后就加入到一個QJsonArray中
QJsonArray newArray={}; for(int i=0;i<resultArray.size();i++){
//Array中的每一項都是一個QJsonValue,可以用toT()方法把它轉化為對應的類型 //由於這里是K-V類型,所以要提取其中的K和V,只能先轉化為QJsonObject QJsonObject jobj = resultArray[i].toObject(); double x = jobj["x"].toDouble(); double y = jobj["y"].toDouble(); int id = i; //用字段構建QJsonObject QJsonObject obj; obj.insert("X",x); obj.insert("Y",y); obj.insert("ID",id); //把QJsonObject放入QJsonArray中 newArray.append(obj); }
2)x,y → QJsonObject → QJsonArray(以QJsonObject為元素) → QJsonDocument → Json文件
說明:有一系列的x,y,每對x,y是一個QJsonObject的屬性,用這些x,y構造QJsonObject;
再把這些QJsonObject作為QJsonArray的元素存入QJsonArray中;
將這個QJsonArray存入QJsonDocument中;
最后用Json文件保存這個QJsonDocument。
①x,y → QJsonObject:
QJsonObject obj; obj.insert("x",x); obj.insert("y",y);
②QJsonObject存入QJsonArray中,作為Array的一個元素:
QJsonArray newArray={}; //之前的obj語句 ... newArray.append(obj);
③QJsonArray → QJsonDocument:
QJsonDocument jsonDoc(newArray);
④QJsonDocument → Json文檔:
QFile file("C:\\Users\\Le\\Desktop\\stationavg.json"); if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) { qDebug()<<"File open error!"; return 0; } file.write(jsonDoc.toJson()); file.flush(); file.close();
3)有兩個List,將它們存入同一個json文件中:2個List → 2個QJsonArray → QJsonObject的兩項 → QJsonDocument → json文件
①List → QJsonArray
//直接用List作為參數構造QJsonArray即可 QJsonArray sedId = {7,8,9,11,12,13,14,15,17,...,95,98,101,102}; QJsonArray numberTransfer={-1,-1,-1,-1,43,30,26,29,...,4,-1,-1,61,54};
②QJsonArray → QJsonObject的一項
//每個Array作為QJsonObject的一項,一共兩項 QJsonObject obj; obj.insert("totalstation",sedId); obj.insert("numbertransfer",numberTransfer);
③QJsonObject → QJsonDocument
QJsonDocument doc = QJsonDocument(obj);
④QJsonDocument → json文件
QFile file("C:\\Users\\Administrator\\Desktop\\totalstation.json"); if(!file.open(QIODevice::WriteOnly | QIODevice::Text)){ qDebug()<<"文件打開錯誤"; return 0; } file.write(doc.toJson(QJsonDocument::Compact));//設置數據組織形式 file.flush(); file.close();
4)反向執行3)中的步驟,由一個json文件得到兩個QList:json文檔 → QJsonDoc → QJsonObject → 兩個QJsonArray → 兩個QList<int>
①json文檔 → QJsonDocument
QFile file("C:\\Users\\Le\\Desktop\\totalstation.json"); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ qDebug()<<"文件打開錯誤"; return 0; } QJsonParseError * error = nullptr; QJsonDocument doc = QJsonDocument::fromJson(file.readAll(),error); if(error){ qDebug()<<"json error"; return 0; } file.close();
②QJsonDocument → QJsonObject
QJsonObject obj = doc.object();
③QJsonObject → 兩個QJsonArray
QJsonArray sedId_JA = obj["totalstation"].toArray(); QJsonArray numberTransfer_JA = obj["numbertransfer"].toArray();
之所以要用toArray(),是因為直接用obj['key']提取到的是QJsonValue類型
④QJsonArray → QList
這里同樣也需要用toInt(),因為QJsonArray中存儲的也是QJsonValue類型
QList<int> sedId={}; QList<int> numberTransfer={}; foreach(QJsonValue v,sedId_JA){ sedId<<v.toInt(); } foreach(QJsonValue v,numberTransfer_JA){ numberTransfer<<v.toInt(); }
7、QJsonArray、QJsonObject、QJsonValue、QJsonDocument之間的關系
①QJsonDocument
QJsonDocument是與Json文檔/QByteArray最接近的類,由於它繼承自QIODevice,所以可以用QIODevice提供的一系列讀寫接口函數進行Json讀寫。
一個QJsonDocument中只能包含一個Object或Array,可以用isArray()、isObject()來檢查。檢查完成后,可以用array()、object()將該QJsonDocument轉換為QJsonArray或QJsonObject。
Object是指,Doc中存儲了一系列的K-V對;
Array是指,Doc中存儲了一個List。
方法
1)QByteArray → QJsonDocument:QJsonDocument::fromJson(QByteArray)
QJsonDocument → QByteArray:QJsonDocument::toJson()
2)QJsonDucument → QJsonArray :array()
3)QJsonDocument → QJsonObject:object()
4)為某個空Doc,填充Array數據:setArray( QJsonArray )
5)為某個空Doc,填充Object數據:setObject( QJsonObject )
②QJsonObject
一個QJsonObject從邏輯上看就是一個Map或Dict,其中存儲了許多K-V對。
用size()可以知道K-V對的數量,由此可以循環訪問每個K-V對。
用 [ key ]或value( key )方法提取key對應的value,這里的Value就是QJsonValue。
③QJsonArray
一個QJsonArray從邏輯上看就是一個List,實際上它與QList的用法基本相同,只是其中存儲的數據都是QJsonValue。
用size()可以知道List的大小,由此可以循環訪問每個元素。
用[ i ]或at( i )方法提取指定位置處的元素,這里的元素就是QJsonValue類型。
④QJsonValue
QJsonValue與我們常見的那些變量沒什么不同,它只是作為QJsonObject和QJsonArray的基本元素而已,可以用toT()將一個QJsonValue轉換為指定基本類型。
如果QJsonValue本身格式就是一個Map,其中存放了若干K-V對,那么可以通過toObject()把它轉化為專門存放K-V對的類型——QJsonObject。
如果QJsonValue本身格式就是一個List,其中存放了若干元素,那么可以通過toArray()把它轉化為邏輯上的List類型——QJsonArray。