Создание массива из объекта Json

#arrays #json #delphi #rad-studio

Вопрос:

У меня есть следующая структура JSON, вызывающая ее из Интернета:

 [
  {
    "Code":"31212",
    "Desc":"JOHN",
    "DOYDESC":"MADRID",
    "Street":"Str41",
    "StreetNo":"86"
  },
  {
    "Code":"30214",
    "Desc":"GEORGE",
    "DOYDESC":"NEW YORK",
    "Street":"Str3",
    "StreetNo":null
  },
  {
    "Code":"09215",
    "Desc":"MARY",
    "DOYDESC":"PARIS",
    "Street":"Str3",
    "StreetNo":"22"
  },
  {
    "Code":"10217",
    "Desc":"MEGAN",
    "DOYDESC":"ROME",
    "Street":"Str4",
    "StreetNo":null
  }
]
 

Я хочу, чтобы пользователь вводил число Edit.Text , а затем выполнял поиск значений Code , чтобы определить, существует ли данное значение.

Есть ли способ создать массив с именем Code со значениями из JSON?

Например, чтобы создать что-то вроде этого:

 Code = ["31212","30214","09215","10217"] 
 

а затем выполнить поиск? Или есть другой способ найти конкретное значение Code из JSON? Я пробовал это до сих пор:

 procedure Tlog_form.Button2Click(Sender: TObject);
var
  jso : TJsonObject;
  jsv,jsval : TJsonValue;
  jsa,jsarr : TJsonArray;
  data,str : string;
  i,j,user : integer;
  jsp : TJsonPair;
  arr : array of string;
begin
  try
    data := GetURLAsString('http://...');
  except
    on E: exception do
  end;

  try
    jsv := TJSONObject.ParseJSONValue(data);

    try
      jsa := jsv as TJSONArray;

      try
        for I := 0 to jsa.Size - 1 do
        begin
          jso := jsa.Get(i) as TJsonObject;
          if jso.ToString = 'Code' then
          begin
            str := jso.GetValue('Code').ToString;

            if Edit1.Text = str then
            begin
              ShowMessage('found it');
            end;

          end;
        end;
      finally
      end;
    finally
      jsv.Free;
    end;
  except
    on E: exception do
  end;
end;
 

Когда я выполняю отладку, он не выдает никаких ошибок. но это все равно не работает.

Ответ №1:

Вы преобразуете каждый TJSONObject элемент массива в a string , а затем сравниваете его с вашим TEdit текстом. Который, очевидно, не будет совпадать. Вам нужно сравнить только Code поля каждого TJSONObject из них, что вы бы сделали, если бы if jso.ToString = 'Code' then полностью удалили проверку, например:

 procedure Tlog_form.Button2Click(Sender: TObject);
var
  jsv : TJSONValue;
  jsa : TJSONArray;
  jso : TJSONObject;
  data, str, code : string;
  I : integer;
begin
  str := Edit1.Text;
  try
    data := GetURLAsString('http://...');
    jsv := TJSONObject.ParseJSONValue(data);
    if jsv <> nil then
    try
      jsa := jsv as TJSONArray;
      for I := 0 to jsa.Size - 1 do
      begin
        jso := jsa.Get(I) as TJSONObject;
        code := jso.GetValue('Code').ToString;
        if str = code then
        begin
          ShowMessage('found it');
        end;
      end;
    finally
      jsv.Free;
    end;
  except
  end;
end;
 

Ответ №2:

Я не уверен, что я вас очень хорошо понимаю, но если вы попытаетесь TALJsonDocument (https://github.com/Zeus64/alcinoe ), у вас есть эта функция:

 Function ALFindJsonNodeByTextChildNodeValue(const JsonNode:TalJsonNode;
                                            Const ChildNodeName: AnsiString;
                                            Const ChildNodeValue : AnsiString;
                                            Const Recurse: Boolean = False): TALJsonNode;