delphidelphi-10.1-berlin

Display string data in message box


Why is this not working with TJSONObject?

procedure TForm1.Button5Click(Sender: TObject);
var
  js : TJSONObject;
  isoDate1, isoDate2, data : string;
begin
  isoDate1 := '2018-01-02T10:00:00.000Z';
  isoDate2 := '2018-01-02T10:10:00.000Z';

  js := TJSONObject.Create;
  js.AddPair(TJsonPair.Create(isoDate1, 'TEST'));
  js.AddPair(TJsonPair.Create(isoDate2, 'TEST2'));

  outputdebugstring(pchar(js.ToString));

  if js.TryGetValue<string>(isoDate1, data) then begin
    ShowMessage(data);
  end else begin
    ShowMessage('data non trouvé pour ' + isoDate1);
  end;
end;

output : Sortie de débogage: {"2018-01-02T10:00:00.000Z":"TEST","2018-01-02T10:10:00.000Z":"TEST2"} Processus Project1.exe (6232)

Expected Outcome:
The TryGetValue should put a string in data
ShowMessage should give me 'TEST' in a message box.

Outcome:
The ShowMessage give me 'data non trouvé pour 2018-01-02T10:00:00.000Z'.


Solution

  • Problem is the dot in your JSON path that you query with the TryGetValue method call. Dot char path parser (TJSONPathParser) interprets as key separator of pairs, whose value is about to be obtained. So, for example call like this:

    if JSONObject.TryGetValue<string>('Foo.Bar', S) then
      DoSomething;
    

    is a query for The value of an object like this:

    {"Foo": {"Bar": "The value"}}
    

    not for The value with the key named this way:

    {"Foo.Bar": "The value"}
    

    So in your case you were trying to query the value of the 2018-01-02T10:00:00 object's key 000Z, which would require object like this:

    {"2018-01-02T10:00:00": {"000Z": "TEST"}}
    

    This JSON path dot notation is hardcoded at this time (without possibility of escaping dot chars in the queried path), so the only way is giving up on that method at this moment, or losing dots from key names.