Перейти к содержанию
Fire Monkey от А до Я
  • 0

Как получить доступ к значениям элементов TJSON?


nek

Вопрос

Доброго времени суток!

Где-то на формуах спрашивал, но потом забросил эту тему) было не до этого...

 

В то время я много читал про Delphi вариант TJSONObject, Array, Items и т.д., но из-за нехватки знаний так и не разобрался в последовательности действий, тем более работаю с C++.

Вариантов и на Сишке куча, но все же у людей частные проблемы вроде утечки памяти, не так сделать, а эдак. Такие заумные вещи мне не по плечу (пока)
Про Data.DBXJSON знаю) Смотрел оф. справку.
 
Вопрос: (и мне бы желательно видеть конкретные рабочие примеры) допустим есть вот такая шняга - ответ ВК API:
 

{
  "response": {
    "count": 1638,
    "items": [
      {
        "id": 168886508,
        "owner_id": -51189706,
        "title": "Jenga Cat",
        "duration": 83,
        "description": "Еще больше крутых видео: vk.com\/just_vid\nРекомендую!",
        "date": 1401295313,
        "views": 754,
        "comments": 5,
        "photo_130": "http:\/\/cs541206.vk.me\/u2949887\/video\/s_af146ce5.jpg",
        "photo_320": "http:\/\/cs541206.vk.me\/u2949887\/video\/l_1b666cdd.jpg",
        "player": "http:\/\/vk.com\/video_ext.php?oid=-51189706&id=168886508&hash=a89ac9f2208445bf",
        "can_comment": 1,
        "can_repost": 1,
        "likes": {
          "user_likes": 0,
          "count": 35
        },
        "repeat": 0
      }
    ]
  }
}

Мне отсюда нужны id, owner_id, player, title в переменные.
 
 
Если группы/пользователя нет, то ответ примерно такой:

{"error":{"error_code":15,"error_msg":"Access denied:  user deactivated","request_params":[{"key":"oauth","value":"1"},{"key":"method","value":"video.get"},{"key":"owner_id","value":"000000000000"},{"key":"v","value":"5.21"},{"key":"count","value":"1"},{"key":"extended","value":"1"},{"key":"access_token","value":"Многа_Букафф"}]}}

Сорри за оффтоп, у TOAuth2Authenticator в модуле REST.Authenticator.OAuth.WebForm.Win.hpp описана форма Tfrm_OAuthWebForm, как её вызвать? Не хочется возиться с IdHTTP/CPPWebBrowser.

 
Ссылка на комментарий

Рекомендуемые сообщения

  • 0
тем более работаю с C++.

Делфи мне не интересен. Т.е. да, там много написано про REST и про порядок действий..мне же надо выдирать уже готовые значения. из ответа

 

На эту статью я натыкался и её обязательно прочитаю...

UPD сорри, вчера быстренько отписался и ушел

Ссылка на комментарий
  • 0

могу только на пример в делфи, ибо С++ не знаю.

Вот код, будут вопросы задавай, отвечу

procedure TForm1.Button1Click(Sender: TObject);
var
  JS : TJSONObject;
  JSAr : TJSONArray;
  s  : string;
begin
  s := Memo1.Text;

  JS := TJSONObject.ParseJSONValue(s) as TJSONObject;
  if Assigned(JS) then
  begin
    JS := TJSONObject.ParseJSONValue(JS.GetValue('response').ToString) as TJSONObject;
    JSAr := TJSONObject.ParseJSONValue(JS.GetValue('items').ToString) as TJSONArray;
    JS   := TJSONObject.ParseJSONValue(JSAr.Items[0].ToString) as TJSONObject;

    Memo1.Clear;
    Memo1.Lines.Add('id: ' + JS.GetValue('id').Value);
    Memo1.Lines.Add('owner_id: ' + JS.GetValue('owner_id').Value);
    Memo1.Lines.Add('player: ' + JS.GetValue('player').Value);
    Memo1.Lines.Add('title: ' + JS.GetValue('title').Value);

    JS.Free;
  end;
end;
Ссылка на комментарий
  • 0

Спасибо) Попробую адаптировать под себя
Оно всё почти идентичное, за исключением некоторых моментов. Например объявление можно впихнуть куда угодно и сразу инициализировать

Ссылка на комментарий
  • 0

Не за что.

Если что спрашивай. 

XML формат мне всегда был противен, хоть и понятен, но все равно внутренне я был против него и как следствие принципиально не использовал в своих программах.

Но вот формат JSON мне очень понравился. Его легко написать от руки, легко читать, даже через регулярки парситься легко, если приспичило. И он не избыточен как XML, а значит по канала связи передается меньше трафика.

 

Так что не бросай этот формат ;)

 

И кстати, что касается утечек. Я когда сам только начинал разбираться в формате JSON и с тем как работать с ним в Delphi, у меня тоже были утечки, ибо я использовал JSON для парсинга ответа с сервера, в потоке. Я тогда начал склоняться к всеобщему мнению что просто сама реализация работы с этим форматом в делфи кривая. 

Но поколебавшись все таки принял во внимание ту мысль, что разработчики Embacadero на девять жизней умнее меня, и вряд ли они выпустили модуль с таким явным глюком. И решил все таки углубиться дальше.

Как оказалось просто поставить JS.Free в конце не достаточно.

Т.е. вот так вот делать не стоит:

var
 JS: TJSONObject;
begin
 s := '{"jsonString":"ok"};
 JS := TJSONObject.ParseJSONValue(s) as TJSONObject;
 ShowMessage(JS.GetValue('jsonString').Value);
 JS.Free;
end;

В процессе работы потока с ним может случиться все что угодно - обрыв связи, тайоут сработает, или некорректные данные, или еще что нибудь. И JS объект может не освободиться. Т.е. поток может уже и не существует, но в оперативке созданный объект лежит.

 

К тому же при таком подходе могут быть и ошибки, например параметра 'jsonString' может и не быть, и все вывалиться в ошибку (но в потоке этого можно и не увидеть) и до JS.Free код никогда не дойдет. А значит будет опять утечка памяти.

 

Так что правильней всего делать через Assigned:

var
 JS: TJSONObject;
begin
 s := '{"jsonString":"ok"}';
 JS := TJSONObject.ParseJSONValue(s) as TJSONObject;
 if Assigned(JS) then 
 begin
  ShowMessage(JS.GetValue('jsonString').Value);
  JS.Free;
 end;
end;

Тогда утечек не будет. Это я теперь точно знаю!)))

Ссылка на комментарий
  • 0
String s = Memo1->Text; //Берём строку из Мемо
TJSONObject* jOb = new TJSONObject(); //Создаём экземпляр класса
jOb->ParseJSONValue(s); //Парсим значение
TJSONPair* jP = jOb->Get(0);//Получаем первый элемент

Как-то так) Коменты конечно же отсебятина)

 

А дальше без dynamic_cast утечка памяти :(

 

Ссылка на комментарий
  • 0
String s = Memo1->Text; //Берём строку из Мемо
TJSONObject* jOb = new TJSONObject(); //Создаём экземпляр класса
jOb->ParseJSONValue(s); //Парсим значение
TJSONPair* jP = jObj->Get(0);//Получаем первый элемент

Как-то так) Коменты конечно же отсебятина)

 

А дальше без dynamic_cast утечка памяти :(

 

А где у тебя аналог Free, после того как ты попользовался всем тем что ты создал? Без освобождения, память будет есть.

Ссылка на комментарий
  • 0

Пример под себя переделал:

#include <Data.DBXJSON.hpp>
#include <memory>
...
std::auto_ptr<TJSONObject> object(static_cast<TJSONObject*>(TJSONObject::ParseJSONValue(Memo1->Lines->Text)));
TJSONObject* response = static_cast<TJSONObject*>(object->Get("response")->JsonValue);
TJSONArray* items = static_cast<TJSONArray*>(response->Get("items")->JsonValue);
TJSONObject* id = static_cast<TJSONObject*>(items->Get(0));
ShowMessage(id->GetValue("id")->ToString());

 

 
Ссылка на комментарий
Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...