• 0
Авторизация  
nek

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

Вопросы

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

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

 

В то время я много читал про 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.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 ответов на этот вопрос

  • 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

Free то ладно) Оно не помогает, delete тоже

delete jOb;
delete jP;

Делал я такое, дело в самих операторах наверное.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 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());

 

 

Поделиться сообщением


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

  • Похожий контент

    • От rareMax
      Как убрать поле класса из сериализации через Rest.Json?
      Вот как я пробую избавиться от поля Foo:
      program Project1; {$APPTYPE CONSOLE} {$R *.res} uses REST.Json, System.JSON.Serializers, System.SysUtils; type TFoo = class private FValue1: Integer; public Value2: Integer; property Value3: Integer read FValue1 write FValue1; end; [JsonSerialize(TJsonMemberSerialization.&Public)] TBar = class private FValue1: Integer; FFoo: TFoo; public Value2: Integer; property Value3: Integer read FValue1 write FValue1; // property Foo: TFoo read FFoo write FFoo; end; procedure Test; var LBar: TBar; begin LBar := TBar.Create; try Writeln(TJson.ObjectToJsonString(LBar)); finally LBar.Free; end; end; begin try { TODO -oUser -cConsole Main : Insert code here } Test; Readln; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. Но на выходе все равно есть поле Foo.
       
    • От ENERGY
      Друзья, нашел тут интересную статью, где тестируются разные jSON парсеры.
       
      Ссылка: http://www.webdelphi.ru/2016/10/ishhem-samyj-bystryj-parser-json-v-delphi/
      Автор: Владислав Баженов
      Описание (26/10/2016):
       
    • От unicorn
      Всем привет. 
      Мне нужно отправить запрос к серверу в формате JSON-RPC. Вопрос - как в него запихнуть json-данные правильно?
    • От Просто Проги
      Пытаюсь получить список друзей из вк получаю их по api записываю в memo.text ответ от get запроса,после пытаюсь получить из json поля
      ответ выглядит так
      { "response": { "count": 104, "items": [ { "id": 1308603, "first_name": "Виктория", "last_name": "Талина", "photo": "http://cs625517.vk.me/v625517603/4e79b/E9Q1WA5SSLiI.jpg", "photo_100": "http://cs625517.vk.me/v625517603/4e79a/15QwerpQbCKk.jpg", "photo_400_orig": "http://cs625517.vk.me/v625517603/4e7199/wxOJQyZhqq8.jpg", "online": 0 }, { "id": 282070, "first_name": "Никита", "last_name": "Багров", "photo": "http://cs630623.vk.me/v630623070/4b610/RXNNdJ6_Nik.jpg", "photo_100": "http://cs630623.vk.me/v630623070/4b60f/MDXpi0deY1A.jpg", "photo_400_orig": "http://cs630623.vk.me/v630623070/4b60e/ec7A3pBDJZ0.jpg", "online": 0 }, "first_name": "Имя ", Следующим кодом
       
      var JSON: TJSONObject; JSONArray: TJSONArray; i: Integer; begin JSON := TJSONObject.ParseJSONValue(Form2.Memo2.Lines.Text) as TJSONObject; сюда получается я заношу весь код Form2.Memo2.Lines.Clear; JSONArray := TJSONArray(JSON.Get('items').JsonValue); далее изу по массиву итмемов for i := 0 to JSONArray.Size - 1 do begin Form2.Memo2.Lines.Add(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('first_name')).JsonValue.Value); пытаюсь добавить найденное поле end; но летят ошибка критичная (
    • От rareMax
      Я работаю с библиотекой XSuperObject. Как правило, сам JSON я не парсю, а только создаю классы-прототипы данных в JSON, и пользуюсь методами .FromJSON и .ToJSON.
      пример:
      Для такого JSON'a 
      создаю такой класс:
      TvktStatus = Class private Ftext: String; FAudio: TvktAudio; published [Alias('text')] property text: String read Ftext write Ftext; [Alias('audio')] property audio: TvktAudio read FAudio write FAudio; End; в итоге не нужно парсить программисту - все делает библиотечка. 
      Теперь к самой проблеме.
      Допустим есть такой файлик с данными в формате JSON:
      Как бы вы составили такой класс-прототип? Ведь тут получается в одном массиве есть как число так и строка.
    • От rareMax
      Поддерживает ли стандартная библиотека маршалинг/демаршалинг классов? Сейчас работаю с XSuperObject - работа очень приятная с ним. Но огорчает то, что тащит за собой тяжелые библиотеки(Инди, БД). Если нет - может кто знает альтернативы полегче? В идеале будет если так же будут Marshalling Attributes
    • От M1shQa
      Получаю с сервера большой JSON, в нем есть поле number. Как получить список в memo состоящий только из номеров? Подскажите пожалуйста..
       
    • От Dion
      Добрый день, Господа.
      Давайте меняться. 
      Предлагаю вам откуда-то взятый мною superobject, версии 1.2 из которой я выкинул разный хлам, допилил и сделал так, чтобы он собирался под Android, OS X и iOS. Протестировал.
      Дальше я написал вокруг него километр кода, создал набор стилей и сделал динамическую загрузку стилей для списка. В список в соответствии со стилями можно добавить порядка 20 разных компонентов.
      Идея моя была такой.
      Есть сервер, на него с клиента загружаются стили и дальше они разливаются от сервера к серверу и в конечном счете попадают на клиентов. Грубо говоря, должен получиться тонкий клиент.
      Надо кому? 
    • От Axbor
      TJSONObject *o = dynamic_cast<TJSONObject*> (TJSONObject::ParseJSONValue(TEncoding::ASCII->GetBytes(s), 0)); if (!o) return; TJSONArray *a = dynamic_cast<TJSONArray*>(o->Get("M")->JsonValue); if (!a) return; for (int i = 0; i < a->Count; i++) { TJSONObject *b = dynamic_cast<TJSONObject*>(a->Get(i)); if (! return; Jokes[i + CurrPos].Caption = b->Pairs[0]->JsonValue->ToString(); Jokes[i + CurrPos].Content = b->Pairs[1]->JsonValue->ToString(); Count++; } delete L; L = 0;  "s" это текст которая хранит JSON внутри значений которого есть символ " (кавычка). В JONS е уже добавлены BackSlash перед такими символами. При парсинге JOSN опят добавляются BackSlash перед спец символами. Как от этого избежать?
    • От Syb
      Я могу совсем что то не правильно делать, хочу получить данные согласно API :
       
       
      http://glonasssoft.ru/wiki/?wiki_name=API
      var jValue:TJSONValue; s,s1:string; begin RestClient1.BaseURL:='http://dev.glonasssoft.ru/auth/login'; Restrequest1.Execute; jValue:=RESTResponse1.JSONValue; s:=jValue.ToString; s1:= copy(s,pos('AuthID:"',s)+11,pos('","U',s)-pos('AuthID:"',s)-11);//достал ключ RestClient2.BaseURL:='http://dev.glonasssoft.ru/vehicles_'; Restrequest2.Params[0].Value:=s1; -здесь параметр типа HttpHeader задан X-Auth в него сую ключ Restrequest2.Execute; - говорит не авторезирован jValue:=RESTResponse2.JSONValue; s:=jValue.ToString; что я не так делаю?
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу