2012-03-07 2 views
6

У меня есть JSON объект, давайте назовем его jObject который выглядит следующим образом:Delphi: Доступ к JSON объектов в массив JSON

{ 
    "id": 0, 
    "data": "[{DAT_INCL: \"08/03/2012 10:07:08\", NUM_ORDE: 1, NUM_ATND: 1, NUM_ACAO: 2, NUM_RESU: 3}, 
      {DAT_INCL: \"08/03/2012 10:07:09\", NUM_ORDE: 2, NUM_ATND: 1, NUM_ACAO: 4, NUM_RESU: 5}, 
      {DAT_INCL: \"08/03/2012 10:07:09\", NUM_ORDE: 3, NUM_ATND: 1, NUM_ACAO: 8, NUM_RESU: NULL}]" 
} 

Как вы можете видеть, он содержит две пары, одна из которых является массивом с тремя объектами в этом случае (количество объектов является динамическим) с несколькими «ключами: значения» (они не меняются, будучи всегда одинаковыми 5 полями), которые я хочу вставить в базу данных SQL, «ключ», являющийся столбец, «значение» - поле. Вопрос в том, как я могу получить доступ к каждому объекту индивидуально?

Code-накрест, что я сделал, было извлечь пару, содержащий этот массив, поместив его в jPair

jPair := OriginalObject.Get(1); 

, а затем захватили массив

jArray:= TJSONArray(jPair.JsonValue); 

(Кроме того, в качестве бонуса, когда Я оцениваю jArray.Size, результат 6226004. Что?)

+0

У вас есть код? –

+0

Я использую XE2 с DBXJSON и DBXJSONReflect. – bpromas

+0

Первоначально у меня был другой JSONObject, поэтому в основном по коду я сделал извлечение пары, содержащей этот массив, поместив его в jPair (dtPair: = OriginalObject.Get (1);), а затем захватил массив (jArray: = TJSONArray (jPair.JsonValue);) (Должен ли я помещать этот код в исходное сообщение?) – bpromas

ответ

8

Если у вас есть массив из DBXJSON, то это TJSONArray. Вызовите его метод Get, чтобы получить элемент массива.

var 
    Value: TJSONValue; 

Value := jArray.Get(0); 

Вы также можете пройти через весь массив с for цикла:

for Value in jArray do 

Но если проверить Size собственность и получить 6226004 вместо 3, что позволяет предположить, что что-то еще не так Вот. Я предполагаю, что то, что вы думаете, это TJSONArray, на самом деле не такой тип. Используйте as сделать проверяемое приведение типа:

jArray := jPair.JsonValue as TJSONArray; 

Вы получите EInvalidCast исключение, если это не удается.

+0

Действительно, я получил исключение EInvalidCast. Означает ли это, что массив, который у меня есть в моем JsonObject, на самом деле не массив? Работа с JSON становится все более и более сложной битвой. – bpromas

+1

Это означает, что это не TJSONArray. Отладчик должен быть в состоянии рассказать вам, что это на самом деле. Если отладчик не говорит вам в подсказке инструмента, тогда отобразите результат вызова 'jPair.JsonValue.ClassName'. –

+0

Да, это TJSONString и плохо отформатированный. Как я могу разобраться в этом? – bpromas

5

вот пример кода для синтаксического анализа и вывода ваших данных json. Я изменил свои данные в формате JSON и добавил ArrayData поля, которым содержит ваш исходный массив объектов:

program Project1; 
{$APPTYPE CONSOLE} 
{$R *.res} 

uses 
    System.SysUtils, dbxjson; 

const JSON_DATA = '{"ArrayData":['+ 
        '{"DAT_INCL":"07/03/2012 17:33:03", "NUM_ORDE":1,"NUM_ATND":1, "NUM_ACAO":2, "NUM_RESU":3},'+ 
        '{"DAT_INCL":"07/03/2012 17:33:05", "NUM_ORDE":2,"NUM_ATND":1, "NUM_ACAO":4, "NUM_RESU":5},'+ 
        '{"DAT_INCL":"07/03/2012 17:33:05", "NUM_ORDE":3,"NUM_ATND":1, "NUM_ACAO":8, "NUM_RESU":null}'+ 
        ']}'; 


var jsv : TJsonValue; 
    originalObject : TJsonObject; 

    jsPair : TJsonPair; 
    jsArr : TJsonArray; 
    jso : TJsonObject; 
    i : integer; 
begin 
    try 
     //parse json string 
     jsv := TJSONObject.ParseJSONValue(JSON_DATA); 
     try 
      //value as object 
      originalObject := jsv as TJsonObject; 

      //get pair, wich contains Array of objects 
      jspair := originalObject.Get('ArrayData'); 
      //pair value as array 
      jsArr := jsPair.jsonValue as TJsonArray; 

      writeln('array size: ', jsArr.Size); 
      //enumerate objects in array 
      for i := 0 to jsArr.Size - 1 do begin 
       writeln('element ', i); 
       // i-th object 
       jso := jsArr.Get(i) as TJsonObject; 

       //enumerate object fields 
       for jsPair in jso do begin 
        writeln(' ', jsPair.JsonString.Value, ': ', jsPair.JsonValue.Value); 
       end; 
      end; 
     finally 
      jsv.Free(); 
      readln; 
     end; 
    except 
     on E: Exception do 
      Writeln(E.ClassName, ': ', E.Message); 
    end; 
end.