※Please understand that I am not good at English, so I am using a translator to ask questions.※
You want to import and use all the values in the JSON array.
However, I completed loading after writing the code, but it seems that only the first or last value comes out. Added array number and tried everything, but did not receive any value or an error occurred.
The code to get the value in JSON array was found and used in the Stack Overflow: Delphi parse JSON array or array
The JSON code is a little different from mine, but I modified it a little and it works well. However, I am asking experts because it is absurd to bring up only the first or last value.
//============JSON CODE===============
[
{
"VehicleWeight": "3.5톤",
"AlightArea": "경남 창원시 성산구 남산동",
"Fee_Driver": "70000",
"LoadArea": "경남 함안군 산인면",
"Commission": "0",
"LiveTime": "2022-08-19 09:39:05",
"AlightDate": "2022-08-19",
"LoadDate": "2022-08-19",
"GoodName": "",
"ActionName": "취소",
"VehicleType": "카고",
"sk": "data#",
"OrderCondition": "3",
"Transport_ID": "B2682B5FC09C4CE38F2F14C84C4829D1",
"pk": "B2682B5FC09C4CE38F2F14C84C4829D1#owner",
"MultiLoading": "0",
"Shipper_Name": "한국거성화물(주)"
},
{
"VehicleWeight": "5톤축",
"AlightArea": "경남 함안군 칠서면",
"Fee_Driver": "130000",
"LoadArea": "경남 창원시 진해구 가주동",
"Commission": "0",
"LiveTime": "2022-08-19 09:00:00",
"AlightDate": "2022-08-19",
"LoadDate": "2022-08-19",
"GoodName": "목재",
"ActionName": "취소",
"VehicleType": "카고",
"sk": "data#",
"OrderCondition": "3",
"Transport_ID": "AB8D6C1ABA30497E95BD6FFF287E47A5",
"pk": "AB8D6C1ABA30497E95BD6FFF287E47A5#owner",
"MultiLoading": "0",
"Shipper_Name": "한국거성화물(주)"
},
{
"VehicleWeight": "2.5톤",
"AlightArea": "대구 달성군 유가읍",
"Fee_Driver": "90000",
"LoadArea": "경남 함안군 대산면",
"Commission": "0",
"LiveTime": "2022-08-19 11:06:24",
"AlightDate": "2022-08-19",
"LoadDate": "2022-08-19",
"GoodName": "",
"ActionName": "취소",
"VehicleType": "카고",
"sk": "data#",
"OrderCondition": "3",
"Transport_ID": "F103B2FC1A8B42C9BCB350A8041BCEA4",
"pk": "F103B2FC1A8B42C9BCB350A8041BCEA4#owner",
"MultiLoading": "0",
"Shipper_Name": "한국거성화물(주)"
},
{
"VehicleWeight": "5톤",
"AlightArea": "경남 밀양시 부북면",
"Fee_Driver": "120000",
"LoadArea": "경남 창원시 의창구 대원동",
"Commission": "0",
"LiveTime": "2022-08-19 09:00:00",
"AlightDate": "2022-08-19",
"LoadDate": "2022-08-19",
"GoodName": "",
"ActionName": "취소",
"VehicleType": "윙바디",
"sk": "data#",
"OrderCondition": "3",
"Transport_ID": "C468AAC449B343CB8CB3349CD9FD46A7",
"pk": "C468AAC449B343CB8CB3349CD9FD46A7#owner",
"MultiLoading": "0",
"Shipper_Name": "한국거성화물(주)"
},
{
"VehicleWeight": "5톤",
"AlightArea": "대전 대덕구",
"Fee_Driver": "220000",
"LoadArea": "경남 함안군 대산면",
"Commission": "0",
"LiveTime": "2022-08-19 10:03:16",
"AlightDate": "2022-08-19",
"LoadDate": "2022-08-19",
"GoodName": "",
"ActionName": "취소",
"VehicleType": "카고",
"sk": "data#",
"OrderCondition": "3",
"Transport_ID": "A89FE76963374084933E89C3BD4CB57C",
"pk": "A89FE76963374084933E89C3BD4CB57C#owner",
"MultiLoading": "0",
"Shipper_Name": "한국거성화물(주)"
},
{
"VehicleWeight": "5톤",
"AlightArea": "경북 칠곡군 약목면",
"Fee_Driver": "120000",
"LoadArea": "경북 영천시 북안면",
"Commission": "0",
"LiveTime": "2022-08-19 09:46:20",
"AlightDate": "2022-08-19",
"LoadDate": "2022-08-19",
"GoodName": "7.5미터",
"ActionName": "취소",
"VehicleType": "윙바디",
"sk": "data#",
"OrderCondition": "3",
"Transport_ID": "846A5E797D9E4A8097D816C83FE0034E",
"pk": "846A5E797D9E4A8097D816C83FE0034E#owner",
"MultiLoading": "0",
"Shipper_Name": "한국거성화물(주)"
},
{
"VehicleWeight": "5톤",
"AlightArea": "경기 화성시 서신면",
"Fee_Driver": "110000",
"LoadArea": "충남 아산시 둔포면",
"Commission": "0",
"LiveTime": "2022-08-19 11:00:00",
"AlightDate": "2022-08-19",
"LoadDate": "2022-08-19",
"GoodName": "",
"ActionName": "등록",
"VehicleType": "카고/윙바디",
"sk": "data#",
"OrderCondition": "1",
"Transport_ID": "780F2633C16542809FBB96ADADFFBA35",
"pk": "780F2633C16542809FBB96ADADFFBA35#owner",
"MultiLoading": "0",
"Shipper_Name": "한국거성화물(주)"
}
]
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, IdSSL , IdSSLOpenSSL, HTTPApp , IdURI,
IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, System.JSON,
Vcl.Grids, Data.DB, Vcl.DBGrids;
type
TForm1 = class(TForm)
DateTimePicker1: TDateTimePicker;
Edit1: TEdit;
Button1: TButton;
IdHTTP1: TIdHTTP;
StringGrid1: TStringGrid;
editPK: TEdit;
Memo1: TMemo;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure StringGrid1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{Automatic column size adjustment}
procedure AutoSizeGridColumn(Grid : TStringGrid; column : integer);
var
i : integer;
temp : integer;
max : integer;
begin
max := 0;
for i := 0 to (Grid.RowCount-1) do
begin
// Among the width of each row in the specified column based on Grid Canvas
// The maximum value is determined by the width of the column
temp := Grid.Canvas.TextWidth(grid.cells[column, i]);
if temp > max then
max := temp;
end;
Grid.ColWidths[column] := max + Grid.GridLineWidth + 20;
end;
{End of autosize Column}
//*************************************************************
//==========================Get JSON array values=========================
function getData(JsonString: String; User: String; Field: String): String;
var
JSonValue: TJSonValue;
JsonArray: TJSONArray;
ArrayElement: TJSonValue;
FoundValue: TJSonValue;
begin
Result :='';
// create TJSonObject from string
JsonValue := TJSonObject.ParseJSONValue(JsonString);
// get the array
JsonArray := JsonValue as TJSONArray;
// iterate the array
for ArrayElement in JsonArray do begin
FoundValue := ArrayElement.FindValue(User);
if FoundValue <> nil then begin
Result := ArrayElement.GetValue<string>(Field);
break;
end;
end;
end;
//==========================End of getting JSON array values=========================
procedure TForm1.Button1Click(Sender: TObject);
var
idhttps: TIdHTTP;
sslIOHandler : TIdSSLIOHandlerSocketOpenSSL;
lStream : TStringStream;
JSONValue : TJSONValue;
JSONArray : TJSONArray;
JSONObject, JSONdata: TJSONObject;
JSONCount: integer;
RESULT : String;
ArrayElement: TJSonValue;
FoundValue: TJSonValue;
i : integer;
begin
Try
Result := '';
idhttps := TIdHTTP.Create();
lStream := TStringStream.Create(nil);
sslIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
Try
sslIOHandler.SSLOptions.Method := sslvSSLv23;
sslIOHandler.SSLOptions.Mode := sslmClient;
idhttps.IOHandler := sslIOHandler;
// idhttps.Request.CustomHeaders.Add(pAuthorization);
idhttps.HandleRedirects :=False;
idhttps.Request.Method := 'GET';
idhttps.Response.ContentType := 'application/json; charset=utf-8';
idhttps.ConnectTimeout := 10000;
idhttps.ReadTimeout := 10000;
lStream.Position := 0;
idhttps.Get('insert JSON URL', lStream, []);
Finally
Result := TEncoding.UTF8.GetString(lStream.Bytes,0, lStream.Size);
JsonArray := TJSONObject.ParseJSONValue(Result) as TJSONArray;
JSONCount := JsonArray.Count;
StringGrid1.RowCount := JSONCount+1;
for i := 0 to (jsonCount)-1 do
for ArrayElement in JsonArray do begin
StringGrid1.Cells[00,i+1] := getdata(Result, '', 'ActionName');//Status
StringGrid1.Cells[02,i+1] := getdata(Result, '', 'Shipper_Name');//Company Name
StringGrid1.Cells[03,i+1] := getdata(Result, '', 'LoadDate');//Different day
StringGrid1.Cells[04,i+1] := getdata(Result, '', 'LoadArea');//to take over
StringGrid1.Cells[05,i+1] := getdata(Result, '', 'AlightArea');//Downloading
StringGrid1.Cells[06,i+1] := getdata(Result, '', 'AlightDate');//Departure Day
StringGrid1.Cells[07,i+1] := getdata(Result, '', 'VehicleType');//model
StringGrid1.Cells[08,i+1] := getdata(Result, '', 'VehicleWeight');// tonnage
StringGrid1.Cells[09,i+1] := getdata(Result, '', 'GoodName');//Cargo information
StringGrid1.Cells[10,i+1] := getdata(Result, '', 'Fee_Driver');//vehicle freight
StringGrid1.Cells[11,i+1] := getdata(Result, '', 'Commission');//commission
StringGrid1.Cells[12,i+1] := getdata(Result, '', 'sk');//pk
StringGrid1.Cells[13,i+1] := getdata(Result, '', 'pk');//sk
{if StringGrid1.Cells[13,i+1] = '300016244318#9977' then
begin
StringGrid1.Cells[01,i+1] := 'O'//연동화물
end
else
begin
StringGrid1.Cells[01,i+1] := '';//연동화물
end; }
end;
{StringGrid1 Auto-Size Cell}
for i := 0 to StringGrid1.ColCount-1 do
begin
AutoSizeGridColumn(StringGrid1, i);
end;
{StringGrid1 Auto-Size Cell END}
FreeAndNil(lStream);
FreeAndNil(idhttps);
FreeAndNil(sslIOHandler);
End;
except
on E: EIdHTTPProtocolException do
begin
Result := e.ErrorMessage;
FreeAndNil(idhttps);
FreeAndNil(sslIOHandler);
end;
End;
end;
end.
I see a lot of problems in this code.
In Button1Click(), the outer for loop is unnecessary and should be removed. Between the two for loops, you are re-looping through the same array over and over needlessly. The inner for..in loop will suffice.
Also, it doesn't make sense to have getValue() take the original JSON as a string, as Button1Click() has already parsed it out, just to have getValue() reparse it again again and again. Lots of wasted overhead. You should pass the existing TJSONArray or even the ArrayElement to getValue() (or better, just eliminate getValue() completely and move its logic into Button1Click directly, especially since your call to FindValue(User) doesn't make sense as User is always blank).
Also, getData() and Button1Click() are both leaking the TJSONValue objects that ParseJSONValue() returns.
Also, you should be using the overload of TIdHTTP.Get() that returns a string instead of fills a TStream.
Also, your try..finallys need some cleanup, you are not adequately protecting all of your objects from errors.
With all of that said, try something more like this instead:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, IdSSL , IdSSLOpenSSL, HTTPApp , IdURI,
IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, System.JSON,
Vcl.Grids, Data.DB, Vcl.DBGrids;
type
TForm1 = class(TForm)
DateTimePicker1: TDateTimePicker;
Edit1: TEdit;
Button1: TButton;
IdHTTP1: TIdHTTP;
StringGrid1: TStringGrid;
editPK: TEdit;
Memo1: TMemo;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure StringGrid1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{Automatic column size adjustment}
procedure AutoSizeGridColumn(Grid : TStringGrid; Column : integer);
var
i : integer;
temp : integer;
max : integer;
begin
max := 0;
for i := 0 to Grid.RowCount-1 do
begin
// Among the width of each row in the specified column based on Grid Canvas
// The maximum value is determined by the width of the column
temp := Grid.Canvas.TextWidth(Grid.Cells[Column, i]);
if temp > max then
max := temp;
end;
Grid.ColWidths[Column] := max + Grid.GridLineWidth + 20;
end;
{End of autosize Column}
//*************************************************************
procedure TForm1.Button1Click(Sender: TObject);
var
idhttps: TIdHTTP;
sslIOHandler : TIdSSLIOHandlerSocketOpenSSL;
JSONValue : TJSONValue;
JSONArray : TJSONArray;
ArrayElement: TJSONValue;
i : integer;
begin
idhttps := TIdHTTP.Create;
try
sslIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(idhttps);
sslIOHandler.SSLOptions.Mode := sslmClient;
sslIOHandler.SSLOptions.Method := sslvSSLv23;
idhttps.IOHandler := sslIOHandler;
// idhttps.Request.CustomHeaders.Add(pAuthorization);
idhttps.HandleRedirects := False;
idhttps.ConnectTimeout := 10000;
idhttps.ReadTimeout := 10000;
idhttps.HTTPOptions := idhttps.HTTPOptions + [hoNoProtocolErrorException, hoWantProtocolErrorContent];
Result := idhttps.Get('insert JSON URL');
finally
idhttps.Free;
end;
JSONValue := TJSONObject.ParseJSONValue(Result);
try
JsonArray := JSONValue as TJSONArray;
StringGrid1.RowCount := JsonArray.Count + 1;
i := 1;
for ArrayElement in JsonArray do
begin
StringGrid1.Cells[00,i] := ArrayElement.GetValue<string>('ActionName','');//Status
StringGrid1.Cells[02,i] := ArrayElement.GetValue<string>('Shipper_Name','');//Company Name
StringGrid1.Cells[03,i] := ArrayElement.GetValue<string>('LoadDate','');//Different day
StringGrid1.Cells[04,i] := ArrayElement.GetValue<string>('LoadArea','');//to take over
StringGrid1.Cells[05,i] := ArrayElement.GetValue<string>('AlightArea','');//Downloading
StringGrid1.Cells[06,i] := ArrayElement.GetValue<string>('AlightDate','');//Departure Day
StringGrid1.Cells[07,i] := ArrayElement.GetValue<string>('VehicleType','');//model
StringGrid1.Cells[08,i] := ArrayElement.GetValue<string>('VehicleWeight','');// tonnage
StringGrid1.Cells[09,i] := ArrayElement.GetValue<string>('GoodName','');//Cargo information
StringGrid1.Cells[10,i] := ArrayElement.GetValue<string>('Fee_Driver','');//vehicle freight
StringGrid1.Cells[11,i] := ArrayElement.GetValue<string>('Commission','');//commission
StringGrid1.Cells[12,i] := ArrayElement.GetValue<string>('sk','');//pk
StringGrid1.Cells[13,i] := ArrayElement.GetValue<string>('pk','');//sk
{if StringGrid1.Cells[13,i] = '300016244318#9977' then
begin
StringGrid1.Cells[01,i] := 'O'//연동화물
end else begin
StringGrid1.Cells[01,i] := '';//연동화물
end;}
Inc(i);
end;
finally
JSONValue.Free;
end;
{StringGrid1 Auto-Size Cell}
for i := 0 to StringGrid1.ColCount-1 do
begin
AutoSizeGridColumn(StringGrid1, i);
end;
{StringGrid1 Auto-Size Cell END}
end;
end.
How do I parse the following Json in Delphi?
This is my first post, and I've taken care to search as much as I can before asking this question,
so please kindly let me know if I posted wrongly in any way.
I would like to get the value of "name_of_centre" in the "records" array
Thank you for any kind assistance.
procedure TForm1.Button1Click(Sender: TObject);
var
i : integer;
jsonRoot: TJSONValue;
jsonObj: TJSONObject;
jsonArr: TJSONArray;
begin
jsonRoot := TJSONObject.ParseJSONValue(memo2.Lines.text);
try
jsonObj := jsonRoot as TJSONObject;
jsonObj := jsonObj.GetValue('result') as TJSONObject;
jsonArr := jsonObj.GetValue('records') as TJSONArray;
showmessage( jsonArr.Count.ToString ); // works ok
for i := 0 to jsonArr.Count - 1 do
begin
jsonObj := jsonArr.Items[i] as TJSONObject;
showmessage( jsonObj.GetValue('name_of_centre').Value ); // error here
end;
finally
jsonRoot.Free;
end;
end;
I've checked out
Delphi parsing a Json with multiple array types?
How to parse this json data in Delphi 10 Seattle?
(especially this one)
and a few other links... but the JSON format seems different.
Any advice?
{
"help": "testing",
"success": true,
"result": {
"resource_id": "data_resource",
"fields": [
{
"type": "int4",
"id": "_id"
},
{
"type": "text",
"id": "name_of_centre"
},
{
"type": "text",
"id": "location_of_centre"
},
{
"type": "text",
"id": "type_of_centre"
},
{
"type": "text",
"id": "owner"
},
{
"type": "numeric",
"id": "no_of_outlets"
},
{
"type": "numeric",
"id": "no_of_branches"
}
],
"records": [
{
"location_of_centre": "Kings Road",
"no_of_outlets": "12",
"no_of_branches": "0",
"name_of_centre": "Kings Road Centre",
"type_of_centre": "HC",
"owner": "Private",
"_id": 1
},
{
"location_of_centre": "Queens",
"no_of_outlets": "14",
"no_of_branches": "1",
"name_of_centre": "Queens Centre",
"type_of_centre": "HC",
"owner": "Public",
"_id": 2
}
],
"_links": {
"start": "ignore",
"next": "ignore2"
},
"limit": 2,
"total": 10
}
}
Thanks for the many replies.
Olivier : I've included the error in this amended code.
Peter : I tried using
jsonRoot.GetValue('result.records[0].name_of_centre')
and it does give me the value of name_of_centre. Good start.
But I'm hoping to get this code to give me the number of items in Array and I iterate the array, instead of hard-code. Thanks.
Remy : strangely though, it works today. It doesn't get Invalid Typecast
at showmessage( jsonObj.GetValue('name_of_centre').Value );
fpiette : I use Delphi 10.3 RIO.
Thanks to everyone for replying.
Is there a need to use jsonRoot.Free; -- i saw this in a posting on stackoverflow.com... How about jsonObj.Free?
jsonRoot := TJSONObject.ParseJSONValue(memo2.Lines.text);
try
jsonObj := jsonRoot as TJSONObject;
jsonObj := jsonObj.GetValue('result') as TJSONObject;
showmessage( jsonObj.ToString );
jsonArr := jsonObj.GetValue('records') as TJSONArray;
showmessage( jsonArr.Count.ToString );
for i := 0 to jsonArr.Count - 1 do
begin
jsonObj := jsonArr.Items[i] as TJSONObject;
if jsonObj .GetValue('name_of_centre').Value = null then
showmessage('null');
// previously had an Invalid Typecast
showmessage( jsonObj.GetValue('name_of_centre').Value );
end;
finally
jsonRoot.Free;
end;
I'm using LkJSON v1.07 to parse JSON in Delphi 7, converting it to TTreeVeiw.
I use this JSON sample from the Internet:
{
"user": {
"pk": 25025320,
"username": "instagram",
"full_name": "Instagram",
"is_private": false,
"profile_pic_id": "1360316971354486387_25025320",
"is_verified": true,
"has_anonymous_profile_picture": false,
"media_count": 5164,
"follower_count": 233901016,
"following_count": 187,
"biography": "Discovering — and telling — stories from around the world.",
"external_url": "",
"usertags_count": 144,
"hd_profile_pic_versions": [
{
"width": 320,
"height": 320,
}
],
"hd_profile_pic_url_info": {
"width": 320,
"height": 320
},
"has_highlight_reels": true,
"auto_expand_chaining": false
},
"status": "ok" ,
}
Here is the relevant Delphi code:
procedure TForm1.PopulateTree;
var
jsDoc : TlkJSONbase;
begin
jsDoc := TlkJSON.ParseText(JSONMemo.Text);
if Assigned(jsDoc) then
begin
JsonTree.Items.Clear;
DomToTree(jsDoc, nil);
end;
end;
procedure TForm1.DomToTree(JsonNode: TlkJSONbase; TreeNode: TTreeNode);
var
I,j: Integer;
NewTreeNode: TTreeNode;
NodeText: string;
jsObj: TlkJSONobject;
jsLst: TlkJSONlist;
n: integer;
begin
case JsonNode.SelfType of
jsObject : begin
jsObj := (JsonNode AS TlkJSONobject);
NodeText := jsObj.NameOf[0] + '[' + jsObj.SelfTypeName + ']';
for I := 0 to jsObj.Count - 1 do
begin
N := jsObj.FieldByIndex[i].Count;
if n > 0 then
NodeText := Format('%s [ %s ] [ %d ]', [jsObj.Nameof[i], jsObj.FieldByIndex[i].SelfTypeName , jsObj.FieldByIndex[i].Count])
else
NodeText := Format('[%s] %s = %s', [jsObj.FieldByIndex[i].SelfTypeName, jsObj.Nameof[i], jsObj.FieldByIndex[i].Value]);
NewTreeNode := JsonTree.Items.AddChild(TreeNode,NodeText);
DomToTree(jsObj.FieldByIndex[i], NewTreeNode);
end;
end;
jsList : begin
jsLst := (JsonNode AS TlkJSONlist);
for I := 0 to jsLst.Count - 1 do
begin
NodeText := jsLst.getString(i);
NewTreeNode := JsonTree.Items.AddChild(TreeNode, NodeText);
end;
end;
jsBase :;
jsNumber :;
jsString :;
jsBoolean : ;
jsNull : ;
end;
end;
The problem is, it does not display the items of the "hd_profile_pic_versions" node, which is identified as jsList. It just displays its name but not the contents, and gives an Invalid Class Typecast error message.
Edit
A screenshot of the application for the biography anomaly
I have this Json
{
"Sucess": true,
"Msg": "OK",
"Ret": {
"First": 0,
"Next": true,
"Total": 60,
"Itens": [
{
"ID": 212121,
"Name": "uuuuuuuuuuuuuuuuuuuuuuuu",
"LcID": 9898,
"Oclao": false,
"Lal": {
"ID": 12202,
"Name": "pppppppppppppppppp",
"Pais": "Brasil",
"Dtc": 0.0
},
"Subtipo": {
"ID": 7458,
"Desc": "mnmnmnmnn"
},
"Tipo": {
"Sit": "cor1",
"Sitrm": 0,
"Name": "Shsdfow"
},
"Qtde": 0,
"Qntcoes": 0,
"Pubum": "adfsdfsdfs",
"Evias": {
"arq": {
"Mo": [
"site.com"
],
"Moir": [
"site.com"
]
}
}
},
{
"ID": 9797878,
"Name": "uuuuuuuuuuuuuuuuuuuuuuuu",
"LcID": 9898,
"Oclao": false,
"Lal": {
"ID": 12332,
"Name": "pppppppppppppppppp",
"Pais": "Brasil",
"Dtc": 0.0
},
"Subtipo": {
"ID": 7458,
"Desc": "mnmnmnmnn"
},
"Tipo": {
"Sit": "cor1",
"Sitrm": 0,
"Name": "Shsdfow"
},
"Qtde": 0,
"Qntcoes": 0,
"Pubum": "adfsdfsdfs",
"Evias": {
"arq": {
"Mo": [
"site.com"
],
"Moir": [
"site.com"
]
}
}
}
]
}
}
however, I can only take the values of the first items "Sucess, Msg and Ret"
I'm doing as follows
var
JSONValue, jv: TJSONValue;
joName: TJSONObject;
data: TBytes;
sHtmlResp, sTemp : String;
begin
sHtmlResp := '[' + sHtmlResp + ']';
data := TEncoding.ASCII.GetBytes(sHtmlResp);
JSONValue := TJSONObject.ParseJSONValue(data, 0);
for jv in JSONValue as TJSONArray do
begin
joName := jv as TJSONObject;
sTemp:= joName.Get('Msg').JSONValue.Value;
end;
end;
sHtmlResp contains the string json.
I've tried some other ways to get the most unsuccessful field, how do I get the sub-items as "Ret", "Items" and so on.
A detail, had to add '[' ']' in the JSON string I get, otherwise I can not get even the first fields.
Thank!
Ret is a subobject so you need to access it as such. It has its own values and an array of subobjects, and so on.
Try this:
var
joName, joRet, joItem: TJSONObject;
joItems: TJSONArray;
sHtmlResp, sMsg: String;
bSuccess: Boolean;
begin
sHtmlResp := ...; // original JSON without added braces around it
joName := TJSONObject.ParseJSONValue(sHtmlResp) as TJSONObject;
bSuccess := joName.GetValue('Success') is TJSONTrue;
// if you are using Delphi 10 Seattle or later, you can use this instead:
// bSuccess := (joName.GetValue('Success') as TJSONBool).AsBoolean;
sMsg := joName.GetValue('Msg').Value;
joRet := joName.GetValue('Ret') as TJSONObject;
// use joRet.GetValue() as needed ...
joItems := joRet.GetValue('Itens') as TJSONArray;
for i := 0 to joItems.Count-1 do
begin
joItem := joItems.Items[i] as TJSONObject;
// use joItem.GetValue() as needed ...
end;
end;
If each object/sub-object have unique ObjectID (name).
The simple way is using this function
function ExtractJsonParm(parm:string;h:string):string;
var r:integer;
begin
r:=pos('"'+Parm+'":',h);
if r<>0 then
result := copy(h,r+length(Parm)+4,pos(',',copy(h,r+length(Parm)+4,length(h)))-1)
else
result:='';
end;
Usage:
begin
Writeln(ExtractJsonParm('First',Value));
Writeln(ExtractJsonParm('Next',Value));
Writeln(ExtractJsonParm('Total',Value));
end;
Outputs:
0
true
60
Using jsonDoc it would be
JSON(sHtmlResp)['Msg']
optionally enclosed in VarToStr to enforce type (and also silently convert Null to empty string value).
As noted in the comments by Remy: no need to enclose in [] as this enforces the outer array.