Проблема: Я использую API для вывода файла JSON как такового, и поэтому не могу редактировать формат JSON-файла. Есть ли способ, чтобы иметь возможность перебирать каждый элемент intraday, чтобы найти значение open в каждой дате?
Я пытался использовать object.intraday[0].open, однако это не работает. Я понимаю, что могу использовать Object.intraday.date.open (где дата, например, «2018-10-19 15:59:00:»); однако я хочу иметь возможность перебирать разные даты.
Пример JSON:
{
"symbol": "AAPL",
"stock_exchange_short": "NASDAQ",
"timezone_name": "America/New_York",
"intraday": {
"2018-10-19 15:59:00:" {
"open": "219.49",
"close": "219.23",
"high": "219.61",
"low": "219.19",
"volume": "302415"
},
"2018-10-19 15:58:00:" {
"open": "219.62",
"close": "219.48",
"high": "219.70",
"low": "219.48",
"volume": "173762"
},
Это pascal-код, который я использую для следующего JSON:
{"intraday":{
"2018-10-1915:59:00": {
"open":"23",
"low":"4"},
"2018-10-1915:58:00":{
"open":"25",
"low":"21"}}}
JSONValue := TJSONObject.ParseJSONValue('{"intraday":{"2018-10-1915:59:00":{"open":"23","low":"4"},"2018-10-1915:58:00":{"open":"25","low":"21"}}}'); j:=0; begin if JSONVAlue is TJSONObject then begin // Get the quote and low values quote := JSONValue.GetValue('intraday[0]'); low := JSONValue.GetValue('intraday.low'); Memo1.Lines.Add(quote + ': ' + low); j := j+1; end; end;
Решение
Вначале разберем JSON-объект, представленный в примере, воспользовавшись нашей программой для просмотра JSON. Что мы видим:
Узел interday представляет собой JSON-объект, который содержит вложенный JSON-объект с уникальным именем — датой. Вложенный JSON-объект, в свою очередь, содержит две пары — open и low, которые и требуется прочитать.
В принципе, ничего сверхъестественного или нового в этом коде нет, за исключением того, что имена вложенных объектов в interday уникальны (они являются датой). Однако это не является серьезной проблемой при работе в Delphi с вложенными JSON-объектами.
Алгоритм решения проблемы может быть следующим:
- Ищем в JSON объект iterday
- в Delphi перечислитель (enumerator) содержащихся в JSON-объекте
- используя возможности перечислителя проходим по парам вложенного объекта JSON и считываем значения из полей open и low.
Так как с момента появления в Delphi «штатных» инструментов для работы с JSON прошло достаточно много времени (впервые модуль System.JSON появился в Delphi XE7), то реализацию приведенного выше алгоритма приведу для Delphi 10.3 Rio.
var JSONValue : TJSONValue; JsonNestedObject: TJSONObject; quote, low: string; begin JSONValue := TJSONObject.ParseJSONValue('{"intraday":{"2018-10-1915:59:00":{"open":"23","low":"4"},"2018-10-1915:58:00":{"open":"25","low":"21"}}}'); begin if JSONVAlue is TJSONObject then begin JsonNestedObject:=JSONVAlue.GetValue('intraday'); with JsonNestedObject.GetEnumerator do //цикл будет выполняться до тех пор, пока в JSON-объекте есть хотя бы одна не пройденная пара while MoveNext do begin //получаем название вложенного объекта (для первого прохода в цикле - это 2018-10-1915:59:00). quote:=Current.JsonString.Value; //считываем значение пары low low:=(Current.JsonValue as TJSONObject).Values['low'].Value; Memo1.Lines.Add(Format('%s, %s', [quote, low])) end; end; end; end;
Как видите, нет ничего сложного в том, чтобы разобрать любой JSON в Delphi и работать со вложенными объектами в JSON. Достаточно знать основы самого JSON и то, какие возможности предоставляет Delphi для работы с ним.

