Search code examples
jsondelphiodataetag

How to get @odata.etag value from JSON in Delphi


Could someone explain me, why @odata.etag key behave different than other keys ? Why I can't get value (and how to get) from it like from other keys ?

using ... System.Generics.Collections, System.JSON

procedure TFMain.Button1Click(Sender: TObject);
var
  JSonValue, SingleValue: TJSonValue;
  ValueArray: TJsonArray;
begin
  JSONValue := TJSONObject.ParseJSONValue('{"@odata.context": "https://blablabla", "value": [{"@odata.etag": "W/\"blablan\"", "No": "X0001" }]}');

  ValueArray := (JSONValue as TJSONObject).GetValue('value') as TJSONArray;
  SingleValue :=  ValueArray.Items[0];

  memo1.Lines.Add(JSONValue.GetValue<string>('value[0].No'));                     //works , no double quotes
  memo1.Lines.Add(JSONValue.GetValue<string>('value[0][email protected]'));            //not works

  memo1.Lines.Add((SingleValue as TJSONObject).GetValue('No').ToString);          //works, double quotes
  memo1.Lines.Add((SingleValue as TJSONObject).GetValue('@odata.etag').ToString); //works, double quotes

  memo1.lines.Add(SingleValue.GetValue<string>('No'));                            //works , no double quotes
  memo1.lines.Add(SingleValue.GetValue<string>('@odata.etag'));                   //not works

end;

Regards.


Solution

  • The answer is simple - because the key contains the dot character (.) which is used as key separator in JSON path and therefore it requires special treatment.

    To access such key in JSON path use quoted indexer:

    Memo1.Lines.Add(JSONValue.GetValue<string>('value[0]["@odata.etag"]'));
    

    Single quoted indexer will work as well. You can also find that in TJSONPathParser documentation.

    On the other hand TJSONObject.GetValue (non-generic method of TJSONObject) works because it takes single key, not the whole path as an argument. You observed double quotes when you used ToString which is expected and very well documented:

    ...
    This format is more readable than the one returned by .ToJSON.
    The string is double-quoted.

    To get the raw string value use Value property:

    memo1.Lines.Add((SingleValue as TJSONObject).GetValue('@odata.etag').Value);