Delphi XE7:如何使用System.JSON更改JSON值(与SuperObject相比)

时间:2015-10-29 23:42:29

标签: json delphi superobject system.json

我需要加载一个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));

似乎没有&#34; SetValue&#34;相当于&#34; GetValue&#34; System.JSON中的方法。

1 个答案:

答案 0 :(得分:4)

TJSONObject支持类似于SuperObject的路径计算器。因此,您不必一次手动钻取一个对象的JSON值树(尽管如果您愿意,也可以这样做)。

但是,System.JSON类实际上并非设计用于修改现有数据(信不信由你)!它们专为解析数据而设计,创建新数据。表示简单值(整数,布尔值,字符串)的所有JSON类都是只读。幸运的是,TJSONPair类允许值替换,因此您必须利用它。

尝试这样的事情:

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;