Delphi XE7:如何使用 System.JSON 更改 JSON 值(相对于 SuperObject)
Delphi XE7: How to change a JSON value using System.JSON (versus SuperObject)
我需要加载一个 JSON 文件,更改一个值,然后将其写回磁盘。
使用 SuperObject 很容易,但是如何使用 System.JSON 单元做同样的事情?
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));
似乎没有 "SetValue" 等同于 System.JSON 中的 "GetValue" 方法。
TJSONObject
确实支持类似于 SuperObject 的路径计算器。因此,您不必一次一个对象地手动钻取 JSON 值树(尽管如果您愿意,当然可以)。
但是,System.JSON
classes 实际上并不是为 修改 现有数据而设计的(信不信由你)!它们专为解析数据和创建新数据而设计。所有表示简单值(整数、布尔值、字符串)的 JSON class 都是 只读 。幸运的是,TJSONPair
class 允许 替换值 ,因此您将不得不利用它。
尝试这样的事情:
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;
我需要加载一个 JSON 文件,更改一个值,然后将其写回磁盘。
使用 SuperObject 很容易,但是如何使用 System.JSON 单元做同样的事情?
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));
似乎没有 "SetValue" 等同于 System.JSON 中的 "GetValue" 方法。
TJSONObject
确实支持类似于 SuperObject 的路径计算器。因此,您不必一次一个对象地手动钻取 JSON 值树(尽管如果您愿意,当然可以)。
但是,System.JSON
classes 实际上并不是为 修改 现有数据而设计的(信不信由你)!它们专为解析数据和创建新数据而设计。所有表示简单值(整数、布尔值、字符串)的 JSON class 都是 只读 。幸运的是,TJSONPair
class 允许 替换值 ,因此您将不得不利用它。
尝试这样的事情:
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;