我在Delphi中有这个Json String,

{
  "bpd": {
    "euro": {
      "buying_rate": "48.50",
      "selling_rate": "52.70"
    },
    "dollar": {
      "buying_rate": "45.30",
      "selling_rate": "45.80"
    },
    "source": "https://www.popularenlinea.com/_api/web/lists/getbytitle('Rates')/items"
  },
  "blh": {
    "euro": {
      "buying_rate": "48.50",
      "selling_rate": "52.00"
    },
    "dollar": {
      "buying_rate": "45.35",
      "selling_rate": "45.80"
    },
    "source": "http://www.blh.com.do/Inicio.aspx"
  }
}


我想提取银行的美元的buy_rate和selling_rate blh

我尝试这个但是我得到了AV

  var
  LJsonObj  : TJSONObject;
  LRows, LElements, LItem : TJSONValue;
begin
    LJsonObj    := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(s),0) as TJSONObject;
  try
     LRows:=LJsonObj.Get(0).JsonValue;
     LElements:=TJSONObject(TJSONArray(LRows).Get(0)).Get(0).JsonValue;
     LItem :=TJSONObject(TJSONArray(LElements).Get(0)).Get(0).JsonValue;
     ShowMessage(TJSONObject(LItem).Get('buying_rate').JsonValue.Value);
  finally
     LJsonObj.Free;
  end;

最佳答案

您的代码中有很多错误。最重要的是您反复使用未经检查的演员表。当你写

TJSONArray(LRows)


您告诉编译器您知道100%可以确保LRowsTJSONArray的后代。好吧,不是。特别是在处理外部数据时,切勿做出此类假设。然后,您将受到收到数据的异想天开。请改用已检查的演员表

LRows as TJSONArray


现在,这仍然是错误的,因为LRows不是数组。实际上,您的JSON根本没有任何数组。它只是有对象。但是,当您使用选中的强制转换时,失败将是有意义的错误,而不是访问冲突。

该程序读取您要查找的值:

{$APPTYPE CONSOLE}

uses
  System.SysUtils, System.JSON, System.IOUtils;

procedure Main;
var
  s: string;
  LJsonObj: TJSONObject;
  blh: TJSONObject;
  dollar: TJSONObject;
  rate: TJSONString;
begin
  s := TFile.ReadAllText('C:\desktop\json.txt');
  LJsonObj := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(s), 0) as TJSONObject;
  try
    blh := LJsonObj.GetValue('blh') as TJSONObject;
    dollar := blh.GetValue('dollar') as TJSONObject;

    rate := dollar.GetValue('buying_rate') as TJSONString;
    Writeln(rate.Value);

    rate := dollar.GetValue('selling_rate') as TJSONString;
    Writeln(rate.Value);
  finally
    LJsonObj.Free;
  end;
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.


输出量

45.35
45.80


我建议您在JSON网站上花费一些时间,以确保您对术语有非常清楚的了解。您应该对术语对象,数组和值的含义有清楚的了解。目前,我认为这是缺乏的。

10-05 22:15