Search code examples
jsondelphidelphi-xe2superobject

SuperObject - Extract All


How to get ALL 'id' member values from a generic JSON. Without knowing structure of it. Because its very complex and it has a lot of sub objects. It has to loop through all the sub objects.

Again for people that keep on asking where is the example JSON. My question is about how to extract a member value in my case "id" from any generic JSON that has this member inside.


Solution

  • If you don't know the structure of the JSON you receive from somewhere, it is important to note that JSON is "simply" a composite pattern and you can traverse it like any other composite structure. The following example traverse the complete structure in a JSON text and prints the path of any member named 'id'.

    procedure ParseJSON;
    var
      JSONText: string;
      JSON: ISuperObject;
    begin
      // Retrieve JSON as a string into JSONText variable any way you like.
      JSON := SO(JSONText);
      ProcessObject(JSON.AsObject);
    end;
    
    procedure ProcessObject(const aAsObject: TSuperTableString; const aPrefix: string = '');
    var
      Names: ISuperObject;
      Name: string;
      Items: ISuperObject;
      Item: ISuperObject;
      idx: Integer;
      Value: string;
      ArrayItem: ISuperObject;
    begin
      if Assigned(aAsObject) then
      begin
        Names := aAsObject.GetNames;
        Items := aAsObject.GetValues;
    
        for idx := 0 to Items.AsArray.Length - 1 do
        begin
          Name := Names.AsArray[idx].AsString;
          Item := Items.AsArray[idx];
          if Item.DataType = stObject then
            Value := '<Object>'
          else if Item.DataType = stArray then
            Value := '<Array>'
          else
            Value := Item.AsString;
    
          if SameText(Name, 'id') then
            WriteLn(Format('%s: %s', [aPrefix + Name, Value]));
    
          if Item.DataType = stArray then
            for ArrayItem in Item do
              ProcessObject(ArrayItem.AsObject, aPrefix + Name + '.');
    
          if Item.DataType = stObject then
            ProcessObject(Item.AsObject, aPrefix + Name + '.');
        end;
      end;
    end;