我想检查json对象中是否有特定的键

b09cbbtk  于 2023-01-14  发布在  其他
关注(0)|答案(2)|浏览(124)

我想检查JSON对象是否有键"error",如果有,我想"继续"循环,否则程序可以转到所有循环。
这是JSON:

[
    {
        "cenario": {
            "origem": "",
            "out": "SNC",
            "country": "",
        },
        "item": "0015963",
        "cod": "17894904009319",
        "nat_rec": null
    },
    {
        "item": "0012868",
        "error": "product unavailable",
        "status": "unavailable",
    }
]

如何检查正在读取的对象是否具有键"error"
我试过:

jValue.FindValue('error') // The problem it's going to search for all objects.
jValue.TryGetValue('error', jArray) // if it doesn't find the key in the index that it's searching at the moment, it breaks the application.

我在做:

response:= IdHTTP.Get(url);

jValue:= TJsonObject.ParseJSONValue(response);

for x := 0 to 2 do
begin
    
  if jValue.TryGetValue('error', jvalue) then
  begin
    continue;
  end;

  memo.Lines.Add('cod_item :' + jValue.GetValue<string>('['+intToStr(x)+'].item'));
  memo.Lines.Add('cod: ' + jValue.GetValue<string>('['+intToStr(x)+'].cod'));
end;
dtcbnfnu

dtcbnfnu1#

在你的代码中,jValue指向一个TJSONArray,所以当你在它上面调用TryGetValue('error')时,你是在数组本身上寻找一个名为'error'的字段,这显然是行不通的,只有在TJONObject上调用它才行。
当查询数组本身的'error'字段时,您需要包括每个对象的索引,例如:

response := IdHTTP.Get(url);

jValue := TJsonObject.ParseJSONValue(response);
try
  jArray := jValue as TJSONArray;
  for x := 0 to jArray.Count-1 do
  begin
    if jArray.FindValue('['+IntToStr(x)+'].error') = nil then
      continue;
    Memo.Lines.Add('cod_item :' + jArray.GetValue<string>('['+IntToStr(x)+'].item'));
    Memo.Lines.Add('cod: ' + jArray.GetValue<string>('['+IntToStr(x)+'].cod'));
  end;
finally
  jValue.Free;
end;

或者,您可以在内存中迭代实际对象,而不是通过路径搜索,例如:

response := IdHTTP.Get(url);

jValue := TJsonObject.ParseJSONValue(response);
try
  jArray := jValue as TJSONArray;
  for x := 0 to jArray.Count-1 do
  begin
    jObj := jArray[x] as TJSONObject;
    if jObj.GetValue('error') = nil then
    begin
      Memo.Lines.Add('cod_item :' + jObj.GetValue('item').Value);
      Memo.Lines.Add('cod: ' + jObj.GetValue('cod').Value);
    end;
  end;
finally
  jValue.Free;
end;
vyswwuz2

vyswwuz22#

你可以把它解析成一个数组,然后迭代这个数组。HasValueAtObjectKey和GetValueAtObjectKey这两个函数演示了两种不同的检查对象键的方法。

program JsonTest;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.JSON;

const TEST_JSON = '[' +
                  '   {' +
                  '       "cenario": {' +
                  '           "origem": "",' +
                  '           "out": "SNC",' +
                  '           "country": ""' +
                  '       },' +
                  '       "item": "0015963",' +
                  '       "cod": "17894904009319",' +
                  '       "nat_rec": null' +
                  '   },' +
                  '   {' +
                  '       "item": "0012868",' +
                  '       "error": "product unavailable",' +
                  '       "status": "unavailable"' +
                  '   }' +
                  ']';

function HasValueAtObjectKey(AKeyName: String; AJsonObject: TJsonObject): Boolean;
var
  LValue: TJsonValue;
begin
  Result := AJsonObject.TryGetValue(AKeyName, LValue);
end;

function GetValueAtObjectKey(AKeyName: String; AJsonObject: TJsonObject; var AHasValue: Boolean): String;
begin
  try
    Result := AJsonObject.GetValue(AKeyName).Value;
    AHasValue := TRUE;
  except
    AHasValue := FALSE;
  end;
end;

begin
  try
    var LArray := TJSONObject.ParseJSONValue(TEST_JSON) as TJSONArray;
    try
      var i:=1;
      for var LArrayValue in  LArray do
      begin
        var LHasValue: Boolean;
        var LErroVal := ValueAtObjectKey('error', (LArrayValue As TJSONObject), LHasValue);
        if LHasValue then
          Writeln('Object ', i, ' Has error: ', LErroVal)
        else
          Writeln('Object ', i, ' Has no error: ');
          Writeln('Object ', i, ' HasValueAtObjectKey: ', HasValueAtObjectKey('error', (LArrayValue As TJSONObject)));
        Inc(i);
      end;
    finally
      LArray.Free;
    end;
    ReadLn;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

相关问题