Recent

Author Topic: Another json problem  (Read 3477 times)

arneolav

  • Full Member
  • ***
  • Posts: 195
    • ElTranslador
Another json problem
« on: February 08, 2022, 11:06:39 pm »
Run into another Json problem here
This does partly work but can't see what's wrong.

NodesArray.count=1, expected 7.

Any help, Thanks in advance.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. type
  3.  
  4.   TData = record
  5.     from,
  6.     too,
  7.     consumptionUnit : string;
  8.  
  9.     cost,
  10.     unitPrice ,
  11.     unitPriceVAT,
  12.     consumption     : double;
  13.  
  14.   end;
  15.  
  16. var
  17.   s: string;
  18.   d, o, p: TJsonData;
  19.   ja, NodesArray: TJsonArray;
  20.   jo: TJsonObject;
  21.   a: array of TData;
  22.   I,J: Integer;
  23.  
  24.   C : String;
  25.   Sl : TStringList;
  26. begin
  27.  
  28.   s := ' {"data":{"viewer":{"homes":[{"consumption":{"nodes":[{"from":"2022-02-08T19:00:00.000+01:00","to":"2022-02-08T20:00:00.000+01:00","cost":null,"unitPrice":1.6671125,"unitPriceVAT":0.3334225,"consumption":null,"consumptionUnit":"kWh"}]}},{"consumption":{"nodes":[{"from":"2022-02-08T19:00:00.000+01:00","to":"2022-02-08T20:00:00.000+01:00","cost":2.23393075,"unitPrice":1.6671125,"unitPriceVAT":0.3334225,"consumption":1.34,"consumptionUnit":"kWh"}]}}]}}}';
  29.  
  30.   d := GetJSON(s);
  31.   Memo1.Append(s);
  32.   o := d.FindPath('data.viewer.homes');
  33.   if (o <> nil) and (o.JSONType = jtArray) then
  34.   begin
  35.     ja := TJsonArray(o);
  36.  
  37.     for I := 0 to ja.Count - 1 do
  38.     begin
  39.       p := ja.Objects[I].FindPath('consumption.nodes');    // <--- TJsonObject found ok
  40.  
  41.       if (p <> nil) and (p.JSONType = jtArray) then
  42.       begin                                                             // <---  TJsonArray found ok
  43.          NodesArray := TJsonArray(p);
  44.          SetLength(a, NodesArray.Count) ;
  45.          for J := 0 to NodesArray.Count - 1 do           // <--- NodesArray.Count = 1, Hmmm
  46.          begin
  47.  
  48.            if (p <> nil) and (p.JSONType = jtObject) then     // <--- TJsonObject NOT found
  49.            begin
  50.               jo := TJsonObject(p);
  51.  
  52.               with a[J] do
  53.               begin
  54.                     from            := jo.Strings['from'];
  55.                     too             := jo.Strings['to'];
  56.                     cost            := jo.Floats['cost'];
  57.                     unitPrice       := jo.Floats['unitPrice'];
  58.                     unitPriceVAT    := jo.Floats['unitPriceVAT'];
  59.                     consumption     := jo.Floats['consumption'];
  60.                     consumptionUnit := jo.Strings['consumptionUnit']
  61.               end;
  62.             end else showmessage('TJsonObject NOT found');
  63.          end;
  64.       end else showmessage('consumption.nodes NOT found');
  65.     end;
  66.   end;
  67.  
  68.   d.Free;
  69.  
  70.   for I := 0 to High(a) do begin
  71.     Memo1.Append('Item ' + I.ToString);
  72.     Memo1.Append('  from: ' + a[I].from);
  73.     Memo1.Append('  to: ' + a[I].too);
  74.     Memo1.Append('  cost: ' + a[I].cost.ToString);
  75.     Memo1.Append('  unitPrice: ' + a[I].unitPrice.ToString);
  76.     Memo1.Append('  unitPriceVAT : ' + a[I].unitPriceVAT.ToString);
  77.     Memo1.Append('  consumption  : ' + a[I].consumption.ToString);
  78.     Memo1.Append('  consumptionUnit: ' + a[I].consumptionUnit);
  79.  
  80.   end;
  81. end;      
« Last Edit: February 10, 2022, 12:36:31 am by arneolav »
Win XP, Win7, Win 10, Win 11, win64 , Lazarus 3.0RC1
Delphi/DevExpress

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Another json problem
« Reply #1 on: February 08, 2022, 11:48:46 pm »
Your json String has only one home with two consumption nodes.

arneolav

  • Full Member
  • ***
  • Posts: 195
    • ElTranslador
Re: Another json problem
« Reply #2 on: February 09, 2022, 12:10:29 am »
Yes, I see, it's received from API like this, but I don't see the problem.
Win XP, Win7, Win 10, Win 11, win64 , Lazarus 3.0RC1
Delphi/DevExpress

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Another json problem
« Reply #3 on: February 09, 2022, 06:00:36 am »
Just in case, your JSON string in formatted form:
Code: Javascript  [Select][+][-]
  1. {
  2.     "data":
  3.     {
  4.         "viewer":
  5.         {
  6.             "homes":
  7.             [
  8.                 {
  9.                     "consumption":
  10.                     {
  11.                         "nodes":
  12.                         [
  13.                             {
  14.                                 "from": "2022-02-08T19:00:00.000+01:00",
  15.                                 "to": "2022-02-08T20:00:00.000+01:00",
  16.                                 "cost": null,
  17.                                 "unitPrice": 1.6671125,
  18.                                 "unitPriceVAT": 0.3334225,
  19.                                 "consumption": null,
  20.                                 "consumptionUnit": "kWh"
  21.                             }
  22.                         ]
  23.                     }
  24.                 },
  25.                 {
  26.                     "consumption":
  27.                     {
  28.                         "nodes":
  29.                         [
  30.                             {
  31.                                 "from": "2022-02-08T19:00:00.000+01:00",
  32.                                 "to": "2022-02-08T20:00:00.000+01:00",
  33.                                 "cost": 2.23393075,
  34.                                 "unitPrice": 1.6671125,
  35.                                 "unitPriceVAT": 0.3334225,
  36.                                 "consumption": 1.34,
  37.                                 "consumptionUnit": "kWh"
  38.                             }
  39.                         ]
  40.                     }
  41.                 }
  42.             ]
  43.         }
  44.     }
  45. }
  46.  
  47.  

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: Another json problem
« Reply #4 on: February 09, 2022, 06:31:23 am »
hello,
you can try something like this :
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2.   type
  3.  
  4.     TData = record
  5.       from,
  6.       too,
  7.       consumptionUnit : string;
  8.  
  9.       cost,
  10.       unitPrice ,
  11.       unitPriceVAT,
  12.       consumption     : double;
  13.  
  14.     end;
  15.  
  16.   var
  17.     s: string;
  18.     d, o, p: TJsonData;
  19.     jo: TJsonObject;
  20.     oEnum: TJsonEnum;
  21.     pEnum: TJsonEnum;
  22.     a: array of TData;
  23.     I,J: Integer;
  24.  
  25.     C : String;
  26.     Sl : TStringList;
  27.   begin
  28.  
  29.     s := ' {"data":{"viewer":{"homes":[{"consumption":{"nodes":[{"from":"2022-02-08T19:00:00.000+01:00","to":"2022-02-08T20:00:00.000+01:00","cost":null,"unitPrice":1.6671125,"unitPriceVAT":0.3334225,"consumption":null,"consumptionUnit":"kWh"}]}},{"consumption":{"nodes":[{"from":"2022-02-08T19:00:00.000+01:00","to":"2022-02-08T20:00:00.000+01:00","cost":2.23393075,"unitPrice":1.6671125,"unitPriceVAT":0.3334225,"consumption":1.34,"consumptionUnit":"kWh"}]}}]}}}';
  30.  
  31.     d := GetJSON(s);
  32.     Memo1.Append(s);
  33.     o := d.FindPath('data.viewer.homes');
  34.     I := 0;
  35.     SetLength(a, o.Count) ;
  36.     for oEnum in o do
  37.       begin
  38.         p := TJsonArray(oEnum.Value).FindPath('consumption.nodes');
  39.         for pEnum in p do
  40.           begin
  41.              jo :=   TJsonObject(pEnum.Value);
  42.              with a[I] do
  43.                 begin
  44.                    if jo.Types['from'] = jtString then
  45.                       from := jo.Strings['from'];
  46.                    if jo.Types['to'] = jtString then
  47.                       too              := jo.Strings['to'];
  48.                    if jo.Types['cost'] = jtNumber then
  49.                       cost            := jo.Floats['cost'];
  50.                    if jo.Types['unitPrice'] = jtNumber then
  51.                       unitPrice       := jo.Floats['unitPrice'];
  52.                    if jo.Types['unitPriceVAT'] = jtNumber then
  53.                       unitPriceVAT    := jo.Floats['unitPriceVAT'];
  54.                    if jo.Types['consumption'] = jtNumber then
  55.                       consumption     := jo.Floats['consumption'];
  56.                    if jo.Types['consumptionUnit'] = jtString then
  57.                       consumptionUnit := jo.Strings['consumptionUnit']
  58.                 end;
  59.               I:= I+1;
  60.            end;
  61.       end;
  62.     d.Free;
  63.  
  64.     for I := 0 to High(a) do begin
  65.       Memo1.Append('Item ' + I.ToString);
  66.       Memo1.Append('  from: ' + a[I].from);
  67.       Memo1.Append('  to: ' + a[I].too);
  68.       Memo1.Append('  cost: ' + a[I].cost.ToString);
  69.       Memo1.Append('  unitPrice: ' + a[I].unitPrice.ToString);
  70.       Memo1.Append('  unitPriceVAT : ' + a[I].unitPriceVAT.ToString);
  71.       Memo1.Append('  consumption  : ' + a[I].consumption.ToString);
  72.       Memo1.Append('  consumptionUnit: ' + a[I].consumptionUnit);
  73.  
  74.     end;
  75.   end;  
   

Résult :
Quote
Item 0
  from: 2022-02-08T19:00:00.000+01:00
  to: 2022-02-08T20:00:00.000+01:00
  cost: 0
  unitPrice: 1,6671125
  unitPriceVAT : 0,3334225
  consumption  : 0
  consumptionUnit: kWh
Item 1
  from: 2022-02-08T19:00:00.000+01:00
  to: 2022-02-08T20:00:00.000+01:00
  cost: 2,23393075
  unitPrice: 1,6671125
  unitPriceVAT : 0,3334225
  consumption  : 1,34
  consumptionUnit: kWh

Friendly, J.P
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

arneolav

  • Full Member
  • ***
  • Posts: 195
    • ElTranslador
Re: Another json problem
« Reply #5 on: February 09, 2022, 10:08:22 am »
Thank's Jurassic Pork
This does the trick.
But I should like to know what's wrong with my code, could it be done that way?
Win XP, Win7, Win 10, Win 11, win64 , Lazarus 3.0RC1
Delphi/DevExpress

arneolav

  • Full Member
  • ***
  • Posts: 195
    • ElTranslador
Re: Another json problem
« Reply #6 on: February 09, 2022, 08:59:18 pm »
As array a was too small on API data I had to do a small correction:
SetLength(a, I+1) ;                             //<---------------------------- View

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2.   type
  3.  
  4.     TData = record
  5.       from,
  6.       too,
  7.       consumptionUnit : string;
  8.  
  9.       cost,
  10.       unitPrice ,
  11.       unitPriceVAT,
  12.       consumption     : double;
  13.  
  14.     end;
  15.  
  16.   var
  17.     s: string;
  18.     d, o, p: TJsonData;
  19.     jo: TJsonObject;
  20.     oEnum: TJsonEnum;
  21.     pEnum: TJsonEnum;
  22.     a: array of TData;
  23.     I,J: Integer;
  24.  
  25.     C : String;
  26.     Sl : TStringList;
  27.   begin
  28.  
  29.     s := ' {"data":{"viewer":{"homes":[{"consumption":{"nodes":[{"from":"2022-02-08T19:00:00.000+01:00","to":"2022-02-08T20:00:00.000+01:00","cost":null,"unitPrice":1.6671125,"unitPriceVAT":0.3334225,"consumption":null,"consumptionUnit":"kWh"}]}},{"consumption":{"nodes":[{"from":"2022-02-08T19:00:00.000+01:00","to":"2022-02-08T20:00:00.000+01:00","cost":2.23393075,"unitPrice":1.6671125,"unitPriceVAT":0.3334225,"consumption":1.34,"consumptionUnit":"kWh"}]}}]}}}';
  30.  
  31.     d := GetJSON(s);
  32.     Memo1.Append(s);
  33.     o := d.FindPath('data.viewer.homes');
  34.     I := 0;
  35.   //  SetLength(a, o.Count) ;      <----------------------------
  36.     for oEnum in o do
  37.       begin
  38.         p := TJsonArray(oEnum.Value).FindPath('consumption.nodes');
  39.         for pEnum in p do
  40.           begin
  41.              jo :=   TJsonObject(pEnum.Value);
  42.              SetLength(a, I+1) ;                             //<----------------------------
  43.              with a[I] do
  44.                 begin
  45.                    if jo.Types['from'] = jtString then
  46.                       from := jo.Strings['from'];
  47.                    if jo.Types['to'] = jtString then
  48.                       too              := jo.Strings['to'];
  49.                    if jo.Types['cost'] = jtNumber then
  50.                       cost            := jo.Floats['cost'];
  51.                    if jo.Types['unitPrice'] = jtNumber then
  52.                       unitPrice       := jo.Floats['unitPrice'];
  53.                    if jo.Types['unitPriceVAT'] = jtNumber then
  54.                       unitPriceVAT    := jo.Floats['unitPriceVAT'];
  55.                    if jo.Types['consumption'] = jtNumber then
  56.                       consumption     := jo.Floats['consumption'];
  57.                    if jo.Types['consumptionUnit'] = jtString then
  58.                       consumptionUnit := jo.Strings['consumptionUnit']
  59.                 end;
  60.               I:= I+1;
  61.            end;
  62.       end;
  63.     d.Free;
  64.  
  65.     for I := 0 to High(a) do begin
  66.       Memo1.Append('Item ' + I.ToString);
  67.       Memo1.Append('  from: ' + a[I].from);
  68.       Memo1.Append('  to: ' + a[I].too);
  69.       Memo1.Append('  cost: ' + a[I].cost.ToString);
  70.       Memo1.Append('  unitPrice: ' + a[I].unitPrice.ToString);
  71.       Memo1.Append('  unitPriceVAT : ' + a[I].unitPriceVAT.ToString);
  72.       Memo1.Append('  consumption  : ' + a[I].consumption.ToString);
  73.       Memo1.Append('  consumptionUnit: ' + a[I].consumptionUnit);
  74.  
  75.     end;
  76.   end;
Win XP, Win7, Win 10, Win 11, win64 , Lazarus 3.0RC1
Delphi/DevExpress

krolikbest

  • Full Member
  • ***
  • Posts: 246
Re: [Solved]Another json problem
« Reply #7 on: February 09, 2022, 10:09:20 pm »
Hi
a little changed yor code.
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  9.   fpjson, jsonparser;
  10.  
  11. type
  12.  
  13.   TData = record
  14.     from,
  15.     too,
  16.     consumptionUnit : string;
  17.  
  18.     cost,
  19.     unitPrice ,
  20.     unitPriceVAT,
  21.     consumption     : double;
  22.   end;
  23.  
  24.   { TForm1 }
  25.  
  26.   TForm1 = class(TForm)
  27.     Button1: TButton;
  28.     Memo1: TMemo;
  29.     procedure Button1Click(Sender: TObject);
  30.   private
  31.  
  32.   public
  33.  
  34.   end;
  35.  
  36. var
  37.   Form1: TForm1;
  38.   s: string;
  39.   d, o, p: TJsonData;
  40.   ja, NodesArray: TJsonArray;
  41.   jo: TJsonObject;
  42.   a: array of TData;
  43.   I: Integer;
  44.  
  45. implementation
  46.  
  47. {$R *.lfm}
  48.  
  49. { TForm1 }
  50.  
  51. procedure TForm1.Button1Click(Sender: TObject);
  52. begin
  53.   s := ' {"data":{"viewer":{"homes":[{"consumption":{"nodes":[{"from":"2022-02-08T19:00:00.000+01:00","to":"2022-02-08T20:00:00.000+01:00","cost":null,"unitPrice":1.6671125,"unitPriceVAT":0.3334225,"consumption":null,"consumptionUnit":"kWh"}]}},{"consumption":{"nodes":[{"from":"2021-02-08T19:00:00.000+01:00","to":"2022-02-08T20:00:00.000+01:00","cost":2.23393075,"unitPrice":1.6671125,"unitPriceVAT":0.3334225,"consumption":1.34,"consumptionUnit":"kWh"}]}}]}}}';
  54.  
  55.   d := GetJSON(s);
  56.   o := d.FindPath('data.viewer.homes');
  57.   if (o <> nil) and (o.JSONType = jtArray) then
  58.   begin
  59.       ja := TJsonArray(o);
  60.  
  61.       memo1.Lines.Add('Count : '+inttostr(ja.Count));
  62.       SetLength(a, ja.Count) ;
  63.  
  64.       for I := 0 to ja.Count - 1 do
  65.       begin
  66.  
  67.         p := ja[i].FindPath('consumption.nodes');
  68.         memo1.Lines.Add('consumption.nodes  '+ inttostr(i));
  69.  
  70.         if (p <> nil) and (p.JSONType = jtArray) then
  71.         begin
  72.            NodesArray := TJsonArray(p);
  73.  
  74.            //c:=nodesArray.Items[0].FindPath('from').AsString;
  75.            //memo1.Lines.Add(c);
  76.  
  77.          jo := TJsonObject(nodesArray.Items[0]); //there is only one item in every consumption.nodes node! that is why index=0
  78.  
  79.          with a[i] do
  80.          begin
  81.            from            := jo.Strings['from'];
  82.            too             := jo.Strings['to'];
  83.            if jo.Types['cost']=jtNumber then
  84.             cost            := jo.Floats['cost'];
  85.            unitPrice       := jo.Floats['unitPrice'];
  86.            unitPriceVAT    := jo.Floats['unitPriceVAT'];
  87.            if jo.Types['consumption']=jtNumber then
  88.             consumption     := jo.Floats['consumption'];
  89.            consumptionUnit := jo.Strings['consumptionUnit']
  90.          end;
  91.         end else showmessage('consumption.nodes NOT found');
  92.  
  93.       end;
  94.   end;
  95.   d.Free;
  96.  
  97.   for I := 0 to High(a) do
  98.   begin
  99.       Memo1.Append('Item ' + I.ToString);
  100.       Memo1.Append('  from: ' + a[I].from);
  101.       Memo1.Append('  to: ' + a[I].too);
  102.       Memo1.Append('  cost: ' + a[I].cost.ToString);
  103.       Memo1.Append('  unitPrice: ' + a[I].unitPrice.ToString);
  104.       Memo1.Append('  unitPriceVAT : ' + a[I].unitPriceVAT.ToString);
  105.       Memo1.Append('  consumption  : ' + a[I].consumption.ToString);
  106.       Memo1.Append('  consumptionUnit: ' + a[I].consumptionUnit);
  107.   end;
  108. end;
  109.  
  110. end.
  111.    

arneolav

  • Full Member
  • ***
  • Posts: 195
    • ElTranslador
Re: [Solved]Another json problem
« Reply #8 on: February 09, 2022, 10:49:49 pm »
Thanks that was interesting!
But, the number of consumption.nodes is unknown, try this:

  s := ' {"data":{"viewer":{"homes":[{"consumption":{"nodes":[{"from":"2022-02-09T20:00:00.000+01:00","to":"2022-02-09T21:00:00.000+01:00","cost":null,"unitPrice":1.566625,"unitPriceVAT":0.313325,"consumption":null,"consumptionUnit":"kWh"},{"from":"2022-02-09T21:00:00.000+01:00","to":"2022-02-09T22:00:00.000+01:00","cost":null,"unitPrice":1.548,"unitPriceVAT":0.3096,"consumption":null,"consumptionUnit":"kWh"}]}},{"consumption":{"nodes":[{"from":"2022-02-09T20:00:00.000+01:00","to":"2022-02-09T21:00:00.000+01:00","cost":4.574545,"unitPrice":1.566625,"unitPriceVAT":0.313325,"consumption":2.92,"consumptionUnit":"kWh"},{"from":"2022-02-09T21:00:00.000+01:00","to":"2022-02-09T22:00:00.000+01:00","cost":5.58828,"unitPrice":1.548,"unitPriceVAT":0.3096,"consumption":3.61,"consumptionUnit":"kWh"}]}}]}}} ';
Win XP, Win7, Win 10, Win 11, win64 , Lazarus 3.0RC1
Delphi/DevExpress

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: [Solved]Another json problem
« Reply #9 on: February 09, 2022, 11:09:41 pm »
It is known, almost. TJsonArray gives you the number of items.

krolikbest's code needs a small change: move
Code: Pascal  [Select][+][-]
  1.   SetLength(a, ja.Count) ;
From line 62 to line 73 and replace ja with NodesArray
Code: Pascal  [Select][+][-]
  1.   SetLength(a, NodesArray.Count) ;

If data.viewer.homes node has more than one home and you want the data of all of them in array a, then change it to:
SetLength(a, Length(a) + NodesArray.Count) ;

You get the idea.

What might cause confusion having ja for homes, and a for nodes.
« Last Edit: February 09, 2022, 11:25:41 pm by engkin »

arneolav

  • Full Member
  • ***
  • Posts: 195
    • ElTranslador
Re: [Solved]Another json problem
« Reply #10 on: February 10, 2022, 12:36:14 am »
Hi!
Move/replace SetLength(a, ja.Count) ;
by
  SetLength(a, NodesArray.Count) ;
Did not work pefekt; don't get values from consumption 3 and 4
I need to have a closer look.
...
Sorry, I was some familiar with XML some years ago, but to Json I'm newbie
Win XP, Win7, Win 10, Win 11, win64 , Lazarus 3.0RC1
Delphi/DevExpress

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: [Solved]Another json problem
« Reply #11 on: February 10, 2022, 02:37:27 am »
hello,
Hi!
Move/replace SetLength(a, ja.Count) ;
by
  SetLength(a, NodesArray.Count) ;
Did not work pefekt; don't get values from consumption 3 and 4
I need to have a closer look.
...
Sorry, I was some familiar with XML some years ago, but to Json I'm newbie
in the Krolikbest's program he considers only one item in the consumption.nodes  node :
Code: Pascal  [Select][+][-]
  1.  jo := TJsonObject(nodesArray.Items[0]); //there is only one item in every consumption.nodes node! that is why index=0
have a look to my program i have a loop for all the items in the consumption.nodes node, so you must add a loop in the Krolikbest's program.
And for a array , it is safe to add one element just before to use it  :
Code: Pascal  [Select][+][-]
  1.     SetLength(a,length(a)+1) ;
  2.          with a[i] do      
you must remove the SetLength before. So the first time, length(a) value is 0 .
i isn't the good index for a you can try a[length(a)-1].
Friendly, J.P
« Last Edit: February 10, 2022, 02:47:25 am by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Another json problem
« Reply #12 on: February 10, 2022, 09:06:42 am »
Hi,
It seems, looking at the structure of the current JSON document, the Pascal structure needed to extract values from it should look something like this:
Code: Pascal  [Select][+][-]
  1. type
  2.   TNode = record
  3.     from,
  4.     too,
  5.     consumptionUnit : string;
  6.     cost,
  7.     unitPrice ,
  8.     unitPriceVAT,
  9.     consumption     : double;
  10.   end;
  11.  
  12.   TConsumption = record
  13.     Nodes: array of TNode;
  14.   end;
  15.  
  16.   THomes = array of TConsumption;
  17.  

Data extracting accordingly:
Code: Pascal  [Select][+][-]
  1. function TryExtractData(const s: string; out aHomes: THomes): Boolean;
  2. var
  3.   Homes, Nodes: TJsonArray;
  4.   CurrNode: TJsonObject;
  5.   jRoot: TJsonData = nil;
  6.   I, J: Integer;
  7. begin
  8.   try
  9.     jRoot := GetJSON(s);
  10.     try
  11.       Homes := TJsonArray(jRoot.FindPath('data.viewer.homes'));
  12.       SetLength(aHomes, Homes.Count);
  13.       for I := 0 to High(aHomes) do begin
  14.         Nodes :=  TJsonArray(Homes[I].FindPath('consumption.nodes'));
  15.         SetLength(aHomes[I].Nodes, Nodes.Count);
  16.         for J := 0 to High(aHomes[I].Nodes) do begin
  17.           CurrNode := Nodes.Objects[J];
  18.           with aHomes[I].Nodes[J], CurrNode do begin
  19.             from := Strings['from'];
  20.             too := Strings['to'];
  21.             consumptionUnit := Strings['consumptionUnit'];
  22.             if Types['cost'] = jtNull then
  23.               cost := 0
  24.             else
  25.               cost := Floats['cost'];
  26.             unitPrice := Floats['unitPrice'];
  27.             unitPriceVAT := Floats['unitPriceVAT'];
  28.             if Types['consumption'] = jtNull then
  29.               consumption := 0
  30.             else
  31.               consumption := Floats['consumption'];
  32.           end;
  33.         end;
  34.       end;
  35.     finally
  36.       jRoot.Free;
  37.     end;
  38.   except
  39.     exit(False);
  40.   end;
  41.   Result := True;
  42. end;
  43.  
  44. procedure TfrmMain.Button1Click(Sender: TObject);
  45. var
  46.   s: string;
  47.   h: THomes;
  48.   I, J: Integer;
  49. begin
  50.   s := ' {"data":{"viewer":{"homes":[{"consumption":{"nodes":[{"from":"2022-02-09T20:00:00.000+01:00","to":"2022-02-09T21:00:00.000+01:00","cost":null,"unitPrice":1.566625,"unitPriceVAT":0.313325,"consumption":null,"consumptionUnit":"kWh"},{"from":"2022-02-09T21:00:00.000+01:00","to":"2022-02-09T22:00:00.000+01:00","cost":null,"unitPrice":1.548,"unitPriceVAT":0.3096,"consumption":null,"consumptionUnit":"kWh"}]}},{"consumption":{"nodes":[{"from":"2022-02-09T20:00:00.000+01:00","to":"2022-02-09T21:00:00.000+01:00","cost":4.574545,"unitPrice":1.566625,"unitPriceVAT":0.313325,"consumption":2.92,"consumptionUnit":"kWh"},{"from":"2022-02-09T21:00:00.000+01:00","to":"2022-02-09T22:00:00.000+01:00","cost":5.58828,"unitPrice":1.548,"unitPriceVAT":0.3096,"consumption":3.61,"consumptionUnit":"kWh"}]}}]}}} ';
  51.   if not TryExtractData(s, h) then
  52.     begin
  53.       Memo1.Append('Failed to extract data');
  54.       exit;
  55.     end;
  56.   for I := 0 to High(h) do begin
  57.     Memo1.Append('Home ' + I.ToString);
  58.     for J := 0 to High(h[I].Nodes) do
  59.       with h[I].Nodes[J] do begin
  60.         Memo1.Append('  Node ' + J.ToString);
  61.         Memo1.Append('    from: ' + from);
  62.         Memo1.Append('    to: ' + too);
  63.         Memo1.Append('    cost: ' + cost.ToString);
  64.         Memo1.Append('    unitPrice: ' + unitPrice.ToString);
  65.         Memo1.Append('    unitPriceVAT: ' + unitPriceVAT.ToString);
  66.         Memo1.Append('    consumption: ' + consumption.ToString);
  67.         Memo1.Append('    consumptionUnit: ' + consumptionUnit);
  68.       end;
  69.   end;
  70. end;
  71.  

It prints
Code: Text  [Select][+][-]
  1. Home 0
  2.   Node 0
  3.     from: 2022-02-09T20:00:00.000+01:00
  4.     to: 2022-02-09T21:00:00.000+01:00
  5.     cost: 0
  6.     unitPrice: 1,566625
  7.     unitPriceVAT: 0,313325
  8.     consumption: 0
  9.     consumptionUnit: kWh
  10.   Node 1
  11.     from: 2022-02-09T21:00:00.000+01:00
  12.     to: 2022-02-09T22:00:00.000+01:00
  13.     cost: 0
  14.     unitPrice: 1,548
  15.     unitPriceVAT: 0,3096
  16.     consumption: 0
  17.     consumptionUnit: kWh
  18. Home 1
  19.   Node 0
  20.     from: 2022-02-09T20:00:00.000+01:00
  21.     to: 2022-02-09T21:00:00.000+01:00
  22.     cost: 4,574545
  23.     unitPrice: 1,566625
  24.     unitPriceVAT: 0,313325
  25.     consumption: 2,92
  26.     consumptionUnit: kWh
  27.   Node 1
  28.     from: 2022-02-09T21:00:00.000+01:00
  29.     to: 2022-02-09T22:00:00.000+01:00
  30.     cost: 5,58828
  31.     unitPrice: 1,548
  32.     unitPriceVAT: 0,3096
  33.     consumption: 3,61
  34.     consumptionUnit: kWh
  35.  

arneolav

  • Full Member
  • ***
  • Posts: 195
    • ElTranslador
Re: Another json problem
« Reply #13 on: February 10, 2022, 10:53:13 am »
Many thanks to avk.
As I am (or at least have been) well acquainted with records and dynastic arrays, this makes it easier to understand Json's structure.

And many thanks to everyone else who has helped me find good solutions, it helps me a lot in the project and saves me a lot of time.
Win XP, Win7, Win 10, Win 11, win64 , Lazarus 3.0RC1
Delphi/DevExpress

 

TinyPortal © 2005-2018