我正在尝试创建一个可以动态地将JSON字段附加到主JSON对象的全局过程。
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
我将我的值存储在名为STATICJSON
的JSON对象中,直到程序关闭,然后我将其保存到文件中。
我正在尝试在STATICJSON
中的某处添加字段。例如;
{
"colors" :
{
"id": "F00",
"color": "red",
"details" : [
{
"name_en": "Red",
},
{
"name_de": "Rot"
}
]
},
{
"id": "0F0",
"color": "green",
"details" : [
{
"name_en": "Green",
},
{
"name_de": "Grün"
}
]
}
}
如果我想在code
数组中的第一个对象的每个details
中添加colors
字段:
obj.addField('colors.0.details.X', 'code');
我的期望:
{
"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"
}
]
}
}
所以我试图使用指针转到第一种颜色的details
数组和addField
。
我正在使用:
STATICJSON:= STATICJSON.GetValue(strArr[i]) as TJSONObject;
并且效果很好,但STATICJSON
内容已更改为:
"details" : [
{
"name_en": "Red",
"code": ""
},
{
"name_de": "Rot",
"code": ""
}
]
所以我丢失了所有其他JSON内容。这就是我想使用指针的原因。但是我在这一行上收到了错误:
pJSONObj:= @(STATICJSON.GetValue(strArr[i]) as TJSONObject);
需要变量
更新:
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;
它有效,但由于这些原因:
STATICJSON:= STATICJSON.GetValue(strArr[i]) as TJSONObject;
STATICJSON:= (STATICJSON.GetValue(strArr[i]) as TJSONArray).Get(StrToInt(strArr[i+1])) as TJSONObject;
我丢失了主要的JSON内容,因此我不想分配STATICJSON
,我只想将其地址分配给指针,以免丢失其内容。
答案 0 :(得分:1)
Delphi对象是引用类型。 TJSONObject
已经是指针,因此无需使用^TJSONObject
。
尝试更像这样的事情:
var
STATICJSON: TJSONObject = nil;
procedure TJSONAdapter.addField(Key, Field: String);
var
I, J, Index: Integer;
strArr: TStringList;
pJSONVal: TJSONValue;
begin
strArr := TStringList.Create;
try
Split('.', Key, strArr);
if STATICJSON = nil then begin
STATICJSON := TJSONObject.Create;
end;
pJSONVal := STATICJSON;
For I := 0 to strArr.Count-1 then
begin
if TryStrToInt(strArr[I], Index) then
begin
if not (pJSONVal is TJSONArray) then Exit;
pJSONVal := TJSONArray(pJSONVal).Get(Index);
end
else if strArr[I] = '*' then
begin
if I <> (strArr.Count-1) then Exit;
if not (pJSONVal is TJSONArray) then Exit;
with TJSONArray(pJSONVal) do
begin
For J := 0 to Count-1 do
begin
pJSONVal := Get(Index);
if pJSONVal is TJSONObject then
TJSONObject(pJSONVal).AddPair(Field, '');
end;
end;
end
else if pJSONVal is TJSONObject then
begin
pJSONVal := TJSONObject(pJSONVal).Get(strArr[I]);
if pJSONVal = nil then Exit;
end
else Exit;
end;
if pJSONVal is TJSONObject then
TJSONObject(pJSONVal).AddPair(Field, '');
finally
strArr.Free;
end;
end;
obj.addField('colors.0.details.*', 'code');