2013-10-09 386 views
1

我需要能夠讀取現有的JSON文件,對其進行修改(例如替換,移除和添加對象,數組和鍵值對),然後再次將文件寫出。Qt修改JSON文件

我一直想讀,寫與這些內容的JSON文件:

{ 
    "array": [ 
     { 
      "name": "Channel", 
      "default": 1 

     }, 
     { 
      "name": "Size", 
      "default": 457 
     } 
    ] 
} 

我讀成功的文件,但在不使用下面的代碼做出任何更改:

QFile File("/path/to/myfile.json"); 
File.open(QIODevice::ReadOnly | QIODevice::Text); 

QJsonParseError JsonParseError; 
QJsonDocument JsonDocument = QJsonDocument::fromJson(File.readAll(), &JsonParseError); 

File.close(); 

QJsonObject RootObject = JsonDocument.object(); 
QJsonArray Array = RootObject.value("array").toArray(); 

QJsonObject ElementOneObject = Array.at(0).toObject(); 

ElementOneObject.insert("key", QJsonValue(QString("value"))); 
ElementOneObject.insert("name", QJsonValue(QString("David"))); 

File.open(QFile::WriteOnly | QFile::Text | QFile::Truncate); 
File.write(JsonDocument.toJson()); 
File.close(); 

我期待看到數組的第一個元素具有新名稱「David」和一個新的鍵值對,如"key" : "value"。此代碼運行後,文件內容相同。我知道文件已被寫出,因爲鍵值對的排序已被更改爲排序爲字母順序的鍵排序。

如何獲取文件以反映我嘗試進行的更改?

回答

5

的原因在問題中的示例不起作用是因爲JsonDocument.object(),RootObject.value("array").toArray()Array.at(0).toObject()都返回數據的副本,而不是引用。有兩種不同的方法來處理這個問題。

1)讓你改變的元素,將其插入陣列的副本後,然後將數組到RootObject副本,然後設置RootObjectJsonDocument

Array.removeAt(0); 
Array.insert(0, ElementOneObject); 
RootObject.insert("array", Array); 
JsonDocument.setObject(RootObject); 

2)使用find()以獲得對要修改的對象/值的引用

QJsonObject RootObject = JsonDocument.object(); 
QJsonValueRef ArrayRef = RootObject.find("array").value(); 
QJsonArray Array = ArrayRef.toArray(); 

QJsonArray::iterator ArrayIterator = Array.begin(); 
QJsonValueRef ElementOneValueRef = ArrayIterator[0]; 

QJsonObject ElementOneObject = ElementOneValueRef.toObject(); 

// Make modifications to ElementOneObject 

ElementOneValueRef = ElementOneObject; 
ArrayRef = Array; 
JsonDocument.setObject(RootObject); 
1

您從該文件創建Json文檔,然後獲取第一個(根)項目RootObject。這不是對JsonDocument中根項目的引用,而是對副本的引用。

因此,從修改後的根項目創建一個新的JsonDocument並保存它。

QJsonDocument doc(RootObject); 

File.open(QFile::WriteOnly | QFile::Text | QFile::Truncate); 
File.write(doc.toJson()); 
File.close(); 

另外,有這個功能,可能只是設置根對象返回到您第一次創建QJsonDocument: -

void QJsonDocument::setObject(const QJsonObject & object) 

所以在保存之前,嘗試調用

JsonDocument.setObject(RootObject); 
+0

我以前嘗試過setObject(),但這還不夠。我認爲問題在於RootObject是一個副本,然後你得到了Array,這也是一個副本,然後你從該數組中獲得一個元素,這也是一個副本!如果我在最後這樣做了,我有它的工作: Array.takeAt(0); Array.insert(0,ElementOneObject); RootObject.insert(「array」,Array); JsonDocument.setObject(RootObject); 雖然這看起來有點瘋狂! – oggmonster

+0

一旦獲得根對象,如果使用find函數,它會將迭代器返回到該鍵的實際數據。這應該允許您在最後調用setObject之前直接更改數據。 – TheDarkKnight