You are not logged in.
Pages: 1
Hi,
I have JSON like this:
{
"ID": 1,
"Childs": [{
"ID": 2,
"Typ": "C1",
"Name1":"X"
}, {
"ID": 3,
"Typ": "C2",
"Name2":"Y"
}
]
}
Childs can have different classes with different types but I have an array with base Child class, so I made something like this:
type
TParentItem = class;
TParentItems = array of TParentItem;
{ TItem }
TItem = class(TSynAutoCreateFields)
private
FID: integer;
published
property ID: integer read FID write FID;
end;
{ TParentItem }
TParentItem = class(TItem)
private
FChilds: TParentItems;
FTestItem: TItem;
published
property TestItem: TItem read FTestItem;
property Childs: TParentItems read FChilds write FChilds;
end;
{ TParentItem1 }
TParentItem1 = class(TParentItem)
private
FName1: string;
published
property Name1: string read FName1 write FName1;
end;
{ TParentItem2 }
TParentItem2 = class(TParentItem)
private
FName2: string;
published
property Name2: string read FName2 write FName2;
end;
How can I choose what class should be made for array item? I have "Typ" value to choose that but making a CustomSerializer wont help becuase it pass a const object and I can change the value of it.
Is there a way to pass a custom create function so in there I can check the "Typ" value and choose that?
Offline
Thanks, but where is it?
If you mean this https://synopse.info/files/html/Synopse … ml#TITL_71 I cant understand how it can help because it need "ClassName" value but I get this JSON from another sever and the value is "Type" for example.
I'm still looking for a solution in documentation and the code and the best I found is something like this and it seems it works.
procedure TestIt;
var
it: TParentItem;
s: RawUTF8;
begin
TJSONSerializer.RegisterObjArrayForJSON([TypeInfo(TParentItems), TParentItem]);
TTextWriter.RegisterCustomJSONSerializer(TypeInfo(TParentItems), TSReaderWriter.ParentItemsReader, nil);
s := StringFromFile('test.json');
it := TParentItem.Create;
ObjectLoadJSON(it, s, nil, [j2oIgnoreUnknownProperty]);
ObjectToJSONFile(it, 'output.json');
it.Free;
end;
{ TSReaderWriter }
class function TSReaderWriter.ParentItemsReader(P: PUTF8Char; var aValue; out aValid: boolean): PUTF8Char;
var
V: TObject absolute aValue;
typ: string;
op:RawUTF8;
begin
aValid := False;
Result := nil;
if (p = nil) then
exit;
if (V = nil) then
begin
op:=UTF8ToString(P);
if typ = 'C1' then
V := TParentItem1.Create
else if typ = 'C2' then
V := TParentItem2.Create
else
V := TParentItem.Create;
end;
result := JSONToObject(aValue, P, aValid, nil, JSONTOOBJECT_TOLERANTOPTIONS);
end;
Last edited by mohsenti (2017-03-26 22:39:02)
Offline
Is this way right from your view?
Offline
Pages: 1