2013-10-09 367 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