ahausladen / JsonDataObjects

JSON parser for Delphi 2009 and newer
MIT License
413 stars 160 forks source link

Array Parsing problem #47

Closed hafedh-trimeche closed 5 years ago

hafedh-trimeche commented 5 years ago

This Json: {"Cards":[{"PAN":"456789","Status":51},{"PAN":"123456","Status":21},{"PAN":"123456","Status":21}]} raised exception when loaded and parsed!

2019-04-02 20_18_18-SPDH - Delphi 10 3 - main  Stopped - Thread IPCMessage (8612)   Built

ahausladen commented 5 years ago

Could it be that you tried to load this JSON String as an Array instead of a Object?

hafedh-trimeche commented 5 years ago

Yes, but I can't predict how the file is organized when loaded from file or stream. ` var FHelper : TJsonObject;

function TJSON.LoadFromFile(const FileName:TFileName): Boolean; var JsonData : TStringStream; begin Result := True; JsonData := TStringStream.Create; try JsonData.LoadFromFile(FileName); if JsonData.DataString='' then JsonData.WriteString('{}'); FHelper.FromJSON(JsonData.DataString); except Result := False; end; FreeAndNil(JsonData); FModified := False; end; `

ahausladen commented 5 years ago

You can use the TJsonBaseObject.Parse/ParseFromFile/ParseFromStream class methods that return a TJsonBaseObject instance that you can test with if MyJsonBaseObject is TJsonArray then

hafedh-trimeche commented 5 years ago

I arranged a Wrap which exposes Root Array element as property

type TJDO = class private JDOBase : TJsonBaseObject; FJDO : TJsonObject; FA : TJsonArray; public constructor Create; destructor Destroy; override; public procedure Load(Content:string); property A:TJsonArray read FA; function IsArray:Boolean; end;

{ TJDO }

constructor TJDO.Create; begin JDOBase := TJsonBaseObject.Parse('{}'); FJDO := JDOBase as TJsonObject; FA := nil; end;

destructor TJDO.Destroy; begin if FA<>nil then FreeAndNil(FA); if FJDO<>nil then FreeAndNil(FJDO); inherited; end;

function TJDO.IsArray: Boolean; begin Result := FA<>nil; end;

procedure TJDO.Load(Content: string); begin if FA<>nil then FreeAndNil(FA); if FJDO<>nil then FreeAndNil(FJDO); JDOBase := TJsonBaseObject.Parse(Content); if JDOBase is TJsonArray then FA := JDOBase as TJsonArray else FJDO := JDOBase as TJsonObject; end;

procedure TForm1.JSONClick(Sender: TObject); const Content = '[{"PAN":"456789","Status":51},{"PAN":"123456","Status":21},{"PAN":"123456","Status":21}]'; var JDO : TJDO; begin JDO := TJDO.Create; JDO.Load(Content); if JDO.IsArray then Memo1.Lines.Text := 'JDO.A[1].S[PAN]: '+JDO.A[1].S['PAN'] else Memo1.Lines.Text := 'Not an Array'; FreeAndNil(JDO); end;