Parsing JSON using Delphi 7

12,006

You are not taking the top-level array into account. This code works for the JSON shown:

var 
  sJSON: String;      
  js, Items, Item: TlkJSONBase;
  I, J: Integer;
begin
  sJSON :=  // as per sample JSON text in question
  js := TlkJSON.ParseText(sJSON);
  for I := 0 to Pred(js.Count) do
  begin
    Items := js.Child[I].Field['items'];
    for J := 0 to Pred(Items.Count) do begin
      Item := Items.Child[J];
      Memo1.Lines.Add(VarToStr(Item.Field['region_id'].Value));
      Memo1.Lines.Add(VarToStr(Item.Field['average_cover'].Value));
      Memo1.Lines.Add(VarToStr(Item.Field['average_growth'].Value));
    end;
  end;
end;
Share:
12,006
Admin
Author by

Admin

Updated on July 05, 2022

Comments

  • Admin
    Admin almost 2 years

    I have a JSON file which I need to parse to extract some values.

    A sample looks like this:

    [
      {
        "period": "2016-06-07 - 2016-06-14",
        "range": "2016-06-07..2016-06-14",
        "items": [
          {
            "region_name": "Canterbury/Otago",
            "region_id": 12,
            "average_cover": 2099,
            "average_growth": 16,
            "reading_count": 3
          },
          {
            "region_name": "Southland",
            "region_id": 14,
            "average_cover": 2068,
            "average_growth": 3,
            "reading_count": 1
          },
          {
            "region_name": "Wairarapa \u0026 Hawkes Bay",
            "region_id": 10,
            "average_cover": 2195,
            "average_growth": 20,
            "reading_count": 2
          }
        ]
      },
      {
        "period": "2016-05-31 - 2016-06-07",
        "range": "2016-05-31..2016-06-07",
        "items": [
          {
            "region_name": "Canterbury/Otago",
            "region_id": 12,
            "average_cover": 2126,
            "average_growth": 17,
            "reading_count": 5
          },
          {
            "region_name": "Southland",
            "region_id": 14,
            "average_cover": 2181,
            "average_growth": 10,
            "reading_count": 2
          }
        ]
      },
      {
        "period": "2016-05-24 - 2016-05-31",
        "range": "2016-05-24..2016-05-31",
        "items": [
          {
            "region_name": "Canterbury/Otago",
            "region_id": 12,
            "average_cover": 2139,
            "average_growth": 28,
            "reading_count": 6
          },
          {
            "region_name": "Central Plateau",
            "region_id": 6,
            "average_cover": 2400,
            "average_growth": 38,
            "reading_count": 1
          },
          {
            "region_name": "Wairarapa \u0026 Hawkes Bay",
            "region_id": 10,
            "average_cover": 2254,
            "average_growth": 27,
            "reading_count": 2
          }
        ]
      },
      {
        "period": "2016-05-18 - 2016-05-25",
        "range": "2016-05-18..2016-05-25",
        "items": [
          {
            "region_name": "Canterbury/Otago",
            "region_id": 12,
            "average_cover": 2183,
            "average_growth": 39,
            "reading_count": 6
          },
          {
            "region_name": "Manawatu",
            "region_id": 9,
            "average_cover": 2315,
            "average_growth": 42,
            "reading_count": 1
          },
          {
            "region_name": "Wairarapa \u0026 Hawkes Bay",
            "region_id": 10,
            "average_cover": 2228,
            "average_growth": 29,
            "reading_count": 2
          }
        ]
      },
      {
        "period": "2016-05-10 - 2016-05-17",
        "range": "2016-05-10..2016-05-17",
        "items": [
          {
            "region_name": "Canterbury/Otago",
            "region_id": 12,
            "average_cover": 2251,
            "average_growth": 40,
            "reading_count": 8
          },
          {
            "region_name": "Otago",
            "region_id": 13,
            "average_cover": 2595,
            "average_growth": 26,
            "reading_count": 1
          },
          {
            "region_name": "Southland",
            "region_id": 14,
            "average_cover": 2526,
            "average_growth": 49,
            "reading_count": 2
          },
          {
            "region_name": "Waikato",
            "region_id": 4,
            "average_cover": 2484,
            "average_growth": 60,
            "reading_count": 1
          },
          {
            "region_name": "Wairarapa \u0026 Hawkes Bay",
            "region_id": 10,
            "average_cover": 2201,
            "average_growth": 34,
            "reading_count": 2
          }
        ]
      }
    ]
    

    The items I am looking to extract are region_id, average_cover, and average_growth.

    I have succeeded in extracting the values from the first items array, but my sample JSON file contains 4 items arrays and I can only seem to extract the values from the first items element.

    I have been using the ulkJSON.pas library and my Delphi code looks like this to send the values to a TMemo on a form:

    var 
      js: TlkJSONBase;
      Items: TlkJSONbase;
      I: Integer;
      lHTTP: TIdHTTP;
      sJSON: String;      
    begin
      sJSON :=  // as per sample JSON text in question
      js := TlkJSON.ParseText(sJSON);
      Items := js.Field['items'];
      for I := 0 to Pred(Items.Count) do begin
        Memo1.Lines.Add(VarToStr(Items.Child[I].Field['region_id'].Value));
        Memo1.Lines.Add(VarToStr(Items.Child[I].Field['average_cover'].Value));
        Memo1.Lines.Add(VarToStr(Items.Child[I].Field['average_growth'].Value));
      end;
    end;