I am trying to create a global procedure which can append a JSON field to a main JSON object dynamically.
procedure TJSONAdapter.addField(Key, Field: String);
var
i: Integer;
strArr: TStringList;
j: Integer;
pJSONObj: ^TJSONObject;
begin
strArr:= TStringList.Create;
Split('.', Key, strArr);
pJSONObj:= @STATICJSON;
i:= 0;
repeat
begin
if IsSimpleJsonValue(STATICJSON.GetValue(strArr[i])) then
begin
Exit;
end;
if STATICJSON.GetValue(strArr[i]) is TJSONObject then
begin
pJSONObj:= @(STATICJSON.GetValue(strArr[i]) as TJSONObject); -> error in this line
if i + 1 = strArr.Count then
begin
I store my values in a JSON object named STATICJSON until the program closes, and then I save it to file.
I am trying to add a field somewhere in STATICJSON. For example;
{
"colors" :
{
"id": "F00",
"color": "red",
"details" : [
{
"name_en": "Red",
},
{
"name_de": "Rot"
}
]
},
{
"id": "0F0",
"color": "green",
"details" : [
{
"name_en": "Green",
},
{
"name_de": "Grün"
}
]
}
}
If I want to add a code field in every details of the first object in the colors array:
obj.addField('colors.0.details.X', 'code');
What I expected :
{
"colors" :
{
"id": "F00",
"color": "red",
"details" : [
{
"name_en": "Red",
"code": ""
},
{
"name_de": "Rot",
"code": ""
}
]
},
{
"id": "0F0",
"color": "green",
"details" : [
{
"name_en": "Green",
},
{
"name_de": "Grün"
}
]
}
}
So I am trying to go to the details array of the first color and addField using a pointer.
I was using:
STATICJSON:= STATICJSON.GetValue(strArr[i]) as TJSONObject;
and it works well, but STATICJSON content is changed to this:
"details" : [
{
"name_en": "Red",
"code": ""
},
{
"name_de": "Rot",
"code": ""
}
]
So I lost all other JSON content. This is why I want to use a pointer. But I'm getting an error on this line:
pJSONObj:= @(STATICJSON.GetValue(strArr[i]) as TJSONObject);
Variable required
UPDATE :
procedure TJSONAdapter.addField(Key, Field: String);
var
i: Integer;
strArr: TStringList;
j: Integer;
begin
strArr:= TStringList.Create;
Split('.', Key, strArr);
i:= 0;
repeat
begin
if IsSimpleJsonValue(STATICJSON.GetValue(strArr[i])) then
begin
Exit;
end;
if STATICJSON.GetValue(strArr[i]) is TJSONObject then
begin
STATICJSON:= STATICJSON.GetValue(strArr[i]) as TJSONObject;
if i + 1 = strArr.Count then
begin
STATICJSON.AddPair(TJSONPair.Create(Field, ''));
Exit;
end;
end;
if STATICJSON.GetValue(strArr[i]) is TJSONArray then
begin
if strArr[i + 1] = 'X' then
begin
for j := 0 to (STATICJSON.GetValue(strArr[i]) as TJSONArray).Size -1 do
begin
((STATICJSON.GetValue(strArr[i]) as TJSONArray).Get(j) as TJSONObject).AddPair(TJSONPair.Create(Field, ''));
end;
Exit;
end;
STATICJSON:= (STATICJSON.GetValue(strArr[i]) as TJSONArray).Get(StrToInt(strArr[i+1])) as TJSONObject;
i:= i+1;
end;
Inc(i);
end;
until i = strArr.Count;
strArr.Free;
end;
It works, but because of these lines:
STATICJSON:= STATICJSON.GetValue(strArr[i]) as TJSONObject;
STATICJSON:= (STATICJSON.GetValue(strArr[i]) as TJSONArray).Get(StrToInt(strArr[i+1])) as TJSONObject;
I lost the main JSON content, so I don't want to assign STATICJSON, i just want to assign its address to a pointer to not lose its content.
TJSONObjectis already a pointer, to an object. So, just for being sure, do you need to have a pointer to a pointer?AddPairorSetPairsorRemovePair