7

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;
2
  • I tried formatting your JSON code for you, but it's apparently not valid JSON. EDIT Actually you forgot to include the opening / closing array brackets ([]). However, even with that, either way I don't see how you could be reading the items object the way your code is written. Commented Jun 15, 2016 at 20:50
  • I reformatted the JSON to make the arrays a little clearer. But yes, the code does not match the JSON shown. Commented Jun 15, 2016 at 22:16

1 Answer 1

6

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;
Sign up to request clarification or add additional context in comments.

1 Comment

That's great. Worked perfectly. Also the error with my original JSON sample text. Much appreciated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.