问题描述
我需要加载一个JSON文件,更改一个值,然后将其写回到磁盘.
I need to load a JSON file, change a value and then write it back to disk.
使用SuperObject很容易,但是如何使用System.JSON单元做同样的事情?
This is easy using SuperObject, but how do I do the same thing using the System.JSON unit?
const
PathToX = 'AllCategories.Category[0].subCategory[0].products[0].views.view[0].x';
var
JsonFilename: string;
JO: ISuperObject; // from the SuperObject unit
JV: TJsonValue; // from the System.Json unit
begin
JsonFilename := ExtractFilePath(Application.ExeName)+'product.json');
// Using the SuperObject unit:
JO := SO(TFile.ReadAllText(JsonFilename));
WriteLn('The old value of "x" is ', JO[PathToX].AsString);
WriteLn('Changing value of x to "123"');
JO.S[PathToX] := '123'; // Set the value of "x"
WriteLn('The new value of "x" is ', JO[PathToX].AsString);
// Now trying to do the same thing using the System.Json unit:
JV := TJSONObject.ParseJsonValue(TFile.ReadAllText(JsonFilename));
WriteLn('The old value of "x" is ', JV.GetValue<string>(PathToX));
WriteLn('Changing value of x to "123"');
// Question: What code should go here to set the value of "x" using System.JSON ???
WriteLn('The new value of "x" is ', JV.GetValue<string>(PathToX));
似乎没有与System.JSON中的"GetValue"方法等效的"SetValue".
There doesn't seem to be a "SetValue" equivalent to the "GetValue" method in System.JSON.
推荐答案
TJSONObject
确实支持类似于SuperObject的路径评估器.因此,您不必一次一次手动钻入JSON值树中的一个对象(尽管您当然可以,但也可以).
TJSONObject
does support a path evaluator similar to SuperObject. So you will not have to manually drill into the JSON value tree one object at a time (though you certainly could if you wanted to).
但是,System.JSON
类实际上不是为修改现有数据而设计的(信不信由你!)!它们专门用于解析数据和创建新数据.所有表示简单值(整数,布尔值,字符串)的JSON类都是只读的.幸运的是,TJSONPair
类允许替换值,因此您将不得不利用它.
However, the System.JSON
classes are actually NOT designed for modifying existing data (believe it or not)! They are designed for parsing data, and creating new data. All of the JSON classes that represent simple values (integers, boolean, strings) are read-only. Fortunately, the TJSONPair
class allows a value to be replaced, so you will have to take advantage of that.
尝试这样的事情:
uses
..., System.JSON;
var
JsonFilename: string;
JV: TJSONValue;
JO: TJSONObject;
JoX: Integer;
JoPair: TJSONPair;
begin
JsonFilename := ExtractFilePath(Application.ExeName) + 'product.json';
JV := TJSONObject.ParseJSONValue(TFile.ReadAllText(JsonFilename));
if JV = nil then raise Exception.Create('Cannot parse file: ' + JsonFilename);
try
JO := JV as TJSONObject;
JoX := JO.GetValue<Integer>('AllCategories.Category[0].subCategory[0].products[0].colors.color[0].views.view[0].x');
WriteLn('The old value of "x" is ', JoX);
WriteLn('Changing value of "x" to "123"');
JoPair := JO.GetValue<TJSONObject>('AllCategories.Category[0].subCategory[0].products[0].colors.color[0].views.view[0]').Get('x');
JoPair.JsonValue.Free;
JoPair.JsonValue := TJSONNumber.Create(123);
WriteLn('The new value of "x" is ', JoPair.JsonValue.Value);
SaveAsDialog.FileName := JsonFilename;
if SaveAsDialog.Execute then TFile.WriteAllText(SaveAsDialog.FileName, JO.ToJSON);
finally
JV.Free;
end;
end;
或者:
uses
..., System.JSON;
var
JsonFilename: string;
JV: TJSONValue;
JO: TJSONObject;
JoX: TJSONPair;
begin
JsonFilename := ExtractFilePath(Application.ExeName) + 'product.json';
JV := TJSONObject.ParseJSONValue(TFile.ReadAllText(JsonFilename));
if JV = nil then raise Exception.Create('Cannot parse file: ' + JsonFilename);
try
JO := JV as TJSONObject;
JoX := JO.GetValue<TJSONObject>('AllCategories.Category[0].subCategory[0].products[0].colors.color[0].views.view[0]').Get('x');
WriteLn('The old value of "x" is ', JoX.JsonValue.Value);
WriteLn('Changing value of "x" to "123"');
JoX.JsonValue.Free;
JoX.JsonValue := TJSONNumber.Create(123);
WriteLn('The new value of "x" is ', JoX.JsonValue.Value);
SaveAsDialog.FileName := JsonFilename;
if SaveAsDialog.Execute then TFile.WriteAllText(SaveAsDialog.FileName, JO.ToJSON);
finally
JV.Free;
end;
end;
这篇关于Delphi XE7:如何使用System.JSON更改JSON值(相对于SuperObject)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!