无法用 Delphi 解析 JSON

Unable to Parse JSON with Delphi

我有一个来自亚马逊的 JSON 字符串。 (https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/index.json) JSON 的顶部看起来像这样...

我需要检索仅包含 offerCode 和 versionIndexUrl 值的列表。我可以阅读一系列报价,但每个报价的密钥都不同,所以我不能使用名称(comprehend、AmazonMWAA 等)。我试过使用元素 [0] 但我得到了 AV。这是我的相关代码...

procedure Load_AWS_Services;
  var 
  json: string;
  idx: Integer;
  obj: TJSONObject;
  j_array: TJSONArray; // the array of all lineitems/offers
  lineItem : TJSONObject;
  ServiceEntry: TJSONPair;

  begin
  try
    
     JSON :=  DownloadFromURLasString('https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/index.json');
     obj := TJSONObject.ParseJSONValue(JSON) as TJSONObject;
     
     try
       // Now parse the data...
       j_array := TJSONArray(obj.Get('offers').JsonValue);
       
       // Now loop through each individual item
       for idx := 0 to pred(j_array.size) do
       begin
      
         lineItem := TJSONObject(j_array.Get(idx));
         Main.Memo1.Lines.Add(lineItem.ToString);  // this shows each offer...so good to this point
        ServiceEntry := lineItem.Pairs[0];
        ShowMessage(ServiceEntry.Value);  // AV here

我需要在最后两行中更改什么才能阅读 'offers' 中的内容?

offers 字段是一个 JSON 对象,而不是 JSON 数组(如果您使用 as 运算符进行 TJSONArray 转换,您会引发 EInvalidCast 异常)。

试试这个:

procedure Load_AWS_Services;
var 
  json: string;
  idx: Integer;
  j_val: TJSONValue;
  j_obj: TJSONObject;
  j_pair: TJSONPair;
  offers: TJSONObject;
  lineItem : TJSONObject;
begin
  try
    json := DownloadFromURLasString('https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/index.json');
    j_val := TJSONObject.ParseJSONValue(json);
    try
      j_obj := j_val as TJSONObject;

      // Now parse the data...
      offers := j_obj.GetValue('offers') as TJSONObject;
       
      // Now loop through each individual item
      for idx := 0 to pred(offers.Count) do
      begin
        j_pair := offers.Get(idx);
        Main.Memo1.Lines.Add(j_pair.JsonString.Value);
        lineItem := j_pair.JsonValue as TJSONObject;
        ShowMessage(lineItem.GetValue('offerCode').Value);
        ShowMessage(lineItem.GetValue('versionIndexUrl').Value);
        ...
      end;
    finally
      j_val.Free;
    end;
  except
    ...
  end;
end;