0

I am trying to generate JSON, data source is a DB FireBird. I have a schema to generate path like this:

schema:= TDictionary<string, string>.Create;
  schema.Add('DBTableName1', 'nest1.valueKeyName1');
  schema.Add('DBTableName2', 'nest1.valueKeyName2');
  schema.Add('DBTableName3', 'nest2.valueKeyName1');
  schema.Add('DBTableName4', 'nest3.valueKeyName1');
  schema.Add('DBTableName5', 'nest3.valueKeyName2');
  schema.Add('DBTableName6', 'nest4.valueKeyName1');

How to create function for generate path to make nested objects?

{
    "nest1": {
        valueKeyName1: DBTableValue1,
        valueKeyName2: DBTableValue2,
    },
    "nest2": {
        valueKeyName1: DBTableValue3 
    },
    "nest5":{
        "nest6": {
            "key1": "value1",
            "key2": "value2",
        },
    "nest7": {}
}

In JavaScript I can do something like:

if (object.hasOwnProperty['key'] == false) object['key'] = {};
object = object['key'];

But in Delphi I have problem, and do not know, how to go deeper:

function TKlient.wprowadzWartoscDoJSON(wartosc: string; JSON: TJSONObject; sciezka: TStringList): TJSONObject;
var
  i: integer;
  obiekt: TJSONObject;
  para: TJSONPair;
  zagniezdzen: integer;

begin
  zagniezdzen := sciezka.Count - 2;
  obiekt := JSON;
  para:= obiekt.Get(sciezka[i]);

  for i := 1 to zagniezdzen do
  begin
    if obiekt.Get(sciezka[i]) = nil then obiekt.AddPair(sciezka[i], TJSONObject.Create)
    else obiekt := obiekt.Get(sciezka[i]);
  end;

  obiekt.AddPair(sciezka[sciezka.Count - 1], wartosc);

  result := obiekt;
end;

1 Answer 1

1

Here I've used a TDictionary<string, TJSONObject> to keep track of the object paths.

var
  schema: TDictionary<string, string>;
  pathSchema: TDictionary<string{path to every object}, TJSONObject>;
  pair: TPair<string, string>;
  values: TStringDynArray;
  jsonObj,
  jsonChildObj,
  jsonParentObj: TJSONObject;
  path: string;
  i: Integer;

begin
  schema := TDictionary<string, string>.Create;
  try
    schema.Add('DBTableName1', 'nest1.valueKeyName1');
    schema.Add('DBTableName2', 'nest1.valueKeyName2');
    schema.Add('DBTableName3', 'nest2.valueKeyName1');
    schema.Add('DBTableName4', 'nest3.valueKeyName1');
    schema.Add('DBTableName5', 'nest3.valueKeyName2');
    schema.Add('DBTableName6', 'nest4.valueKeyName1');
    schema.Add('value1',       'nest5.nest6.key1');
    schema.Add('value2',       'nest5.nest6.key2');

    pathSchema := TDictionary<string, TJSONObject>.Create;
    try

      jsonObj := TJSONObject.Create;
      try
        for pair in schema do begin
          values := SplitString(pair.Value, '.');
          path := '';
          jsonParentObj := jsonObj;
          for i := Low(values) to High(values)-1 do begin
            if i > 0 then
              path := path + '.';
            path := path + values[i];
            if pathSchema.ContainsKey(path) then
              jsonChildObj := pathSchema[path]
            else begin
              jsonChildObj := TJSONObject.Create;
              jsonParentObj.AddPair(TJSONPair.Create(values[i], jsonChildObj));
              pathSchema.Add(path, jsonChildObj);
            end;
            jsonParentObj := jsonChildObj;
          end;
          jsonChildObj.AddPair(TJSONPair.Create(values[High(values)], pair.Key));
        end;

        WriteLn(jsonObj.ToString);

      finally
        jsonObj.Free;
      end;

    finally
      pathSchema.Free;
    end;

  finally
    schema.Free;
  end;

  ReadLn;

end.

The above prints the following:

{
    "nest4":{
        "valueKeyName1":"DBTableName6"
    },
    "nest2":{
        "valueKeyName1":"DBTableName3"
    },
    "nest5":{
        "nest6":{
            "key1":"value1",
            "key2":"value2"
        }
    },
    "nest1":{
        "valueKeyName1":"DBTableName1",
        "valueKeyName2":"DBTableName2"
    },
    "nest3":{
        "valueKeyName1":"DBTableName4",
        "valueKeyName2":"DBTableName5"
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.