C++Builder
  Начало   Форум   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: Разбор json  (Прочитано 5687 раз)
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


« : 11 Март 2015, 17:51:34 »

Как этот код будет на С++?
TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(GJSONString), 0) as TJSONObject;
Источник:
http://docwiki.embarcadero.com/RADStudio/XE7/en/JSON
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


« Ответ #1 : 11 Март 2015, 18:17:09 »

Что тут добавить чтобы откомпилировалось?
#include
#include

 std::unique_ptr LJSONObject(new TJSONObject());
 String GJSONString = L"текст";
 LJSONObject = dynamic_cast(TJSONObject::ParseJSONValue(TEncoding::ASCII->GetBytes(GJSONString), 0));


[bcc32 Error] WebModuleUnit1.cpp(54): E2285 Could not find a match for 'operator std::unique_ptr >::= <_Ty2,_Dx2>(TJSONObject *)'
  Full parser context
    WebModuleUnit1.cpp(22): parsing: void _fastcall TWebModule1::WebModule1DefaultHandlerAction(TObject *,TWebRequest *,TWebResponse *,bool &)
Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


« Ответ #2 : 12 Март 2015, 13:13:56 »

Код
std::unique_ptr<TStringStream> pDataStream(new TStringStream());
pDataStream->WriteString(L"{\"one\": 1, \"two\": 2, \"three\": [1, 2, 3]}");
TJSONValue* Val = TJSONObject::ParseJSONValue(pDataStream->DataString);
if(Val) { ... }
 
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


« Ответ #3 : 12 Март 2015, 15:01:04 »

Большое спасибо!
Вот еще такой вариант нашелся:
Код:
  String GJSONString = L"{\"Счетчик №\": 12345}";
  std::unique_ptr LJSONValue(TJSONObject::ParseJSONValue(GJSONString));
  TJSONObject *LJSONObject = dynamic_cast(LJSONValue.get());
  if(LJSONObject != NULL)
          {

Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


« Ответ #4 : 16 Март 2015, 11:26:20 »

Подскажите, пожалуйста, почему этот код вызывает AV
Код:
 String GJSONString = Sdata;
 std::unique_ptr LJSONValue(TJSONObject::ParseJSONValue(GJSONString));
 TJSONObject *LJSONObject = dynamic_cast(LJSONValue.get());
 if(LJSONObject != NULL)
{

for (int i = 0; i < LJSONObject->Size(); i++)
 {
                           //если закомментировать цикл AV нет  
                           std::unique_ptr JSONPair(LJSONObject->Get(i));
  String JsonMemberName = JSONPair->JsonString->Value();
  //используем JsonMemberName

 }

  }
Access violation at address 00045012 in module 'pascalservertcp.exe'. Read of address 00045012
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


« Ответ #5 : 16 Март 2015, 13:00:49 »

Похожу что TJSONPair не надо создавать через new...
Вроде так работает:
Код
  String GJSONString = JsonData;
 std::unique_ptr<TJSONValue> LJSONValue(TJSONObject::ParseJSONValue(GJSONString));
 TJSONObject *LJSONObject = dynamic_cast<TJSONObject*>(LJSONValue.get());
 
 if(LJSONObject != NULL)
{
TJSONPair* JSONPair;
for (int i = 0; i < LJSONObject->Size(); i++)
 {
  JSONPair = LJSONObject->Get(i);
  if(JSONPair != NULL)
  {
String JsonMemberName = JSONPair->JsonString->Value();
//***
  }
 
 }
 
}
 
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


« Ответ #6 : 16 Март 2015, 15:53:03 »

Подскажите оптимальный код.

Код
//разбор TJSONArray по имени sens в пакете json
void ParseJsonArraySens(String CoderjimoeJsonArraySens)
{
 
 String GJSONString = CoderjimoeJsonArraySens;
 std::unique_ptr<TJSONValue> LJSONValue(TJSONObject::ParseJSONValue(GJSONString));
 TJSONObject *LJSONObject = dynamic_cast<TJSONObject*>(LJSONValue.get());
 if(LJSONObject != NULL)
{
TJSONPair * JSONPair;
String JsonMemberArraySensName;
String JsonMemberArraySensValue;
for (int i = 0; i < LJSONObject->Size(); i++)
{
 
JSONPair = LJSONObject->Get(i);
if(JSONPair != NULL)
  {
JsonMemberArraySensName = JSONPair->JsonString->Value();
JsonMemberArraySensValue = JSONPair->JsonValue->ToString();
String result = JsonMemberArraySensName + L" : " + JsonMemberArraySensValue;
ZapisVRichEditWindow(result);
  }
 
 
}
}
 
 
}
//---------------------------------------------------------------------------
//сначала вызов этой функции - сюда приходи json пакет
//разбор заголовка json пакета
void ParseJSONValue(String JsonData)
{
 String GJSONString = JsonData;
 std::unique_ptr<TJSONValue> LJSONValue(TJSONObject::ParseJSONValue(GJSONString));
 TJSONObject *LJSONObject = dynamic_cast<TJSONObject*>(LJSONValue.get());
 
 if(LJSONObject != NULL)
{
TJSONPair * JSONPair;
TJSONArray * JsonArraySens;
String JsonMemberName;
String JsonMemberValue;
for (int i = 0; i < LJSONObject->Size(); i++)
 {
  /*
  разбор:
  "login": "логин",
  "auth":"nn..nn",
  "id":"190",
  "sens":
  */

 
  JSONPair = LJSONObject->Get(i);
  if(JSONPair != NULL)
  {
JsonMemberName = JSONPair->JsonString->Value();
JsonMemberValue = JSONPair->JsonValue->ToString();
//тестовая проверка
//вывод "login": "логин","auth":"nn..nn","id":"190","sens":
String result = JsonMemberName + " : " + JsonMemberValue;
ZapisVRichEditWindow(result); //показать в RichEdit
 
//подготовка к разбору TJSONArray по имени sens в пакете json
if(JsonMemberName.Trim() == L"sens")
{
 
  JsonArraySens = dynamic_cast<TJSONArray*>(LJSONObject->Get(L"sens")->JsonValue);
 
  if(JsonArraySens != NULL)
{
 
 String CoderjimoeJsonArraySens;
 for (int i = 0; i < JsonArraySens->Size(); i++)
{
  CoderjimoeJsonArraySens = JsonArraySens->Get(i)->ToString();
  //отправим на разбор TJSONArray по имени sens в пакете json
  ParseJsonArraySens(CoderjimoeJsonArraySens);
}
 
 
  //ZapisVRichEditWindow(CoderjimoeJsonArraySens);//показать в RichEdit
 
 
}
 
}//if(JsonMemberName.Trim() == L"sens")
 
 
 
  }//if(JSONPair != NULL)
 
 }
 
}
 
}
 
 
« Последнее редактирование: 17 Март 2015, 17:11:32 от SilverFish » Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


« Ответ #7 : 17 Март 2015, 16:15:06 »

Сразу скажу, в твой код не вдавался, ибо лень  
Вот кусок из моего класса для превращения JSON в текст (в читаемом виде):

Код
const String STR_OFFSET = "  ";
 
 
System::UnicodeString __fastcall TJsonSettingsBase::Prettify(const String& AStr)
{
std::unique_ptr<TStringList> slRows(new TStringList);
slRows->Text = AStr;
 
// remove blank lines
for(int i=0; i<slRows->Count; i++) {
if(slRows->Strings[i].IsEmpty()) {
slRows->Delete(i); --i;
       }
}
 
// indent
int Brackets(0);
String sLeft;
_TCHAR wch;
 
for(int i=0; i<slRows->Count; i++) {
 
sLeft = TrimLeft(slRows->Strings[i]);
wch = sLeft[1];
 
if(wch=='{' || wch=='[') {
slRows->Strings[i] =
Strutils::DupeString(STR_OFFSET, Brackets) + sLeft;
 
Brackets++;
}
 
else if(wch=='}' || wch==']') {
Brackets--;
 
slRows->Strings[i] =
Strutils::DupeString(STR_OFFSET, Brackets) + sLeft;
}
 
else {
        slRows->Strings[i] =
Strutils::DupeString(STR_OFFSET, Brackets) + slRows->Strings[i];
       }
 
}
 
 
   return slRows->Text;
}
 
//---------------------------------------------------------------------------
 
System::UnicodeString __fastcall TJsonSettingsBase::ToStringPretty(TJSONValue* const AValue)
{
std::unique_ptr<TStringBuilder> pOut(new TStringBuilder());
 
TJSONArray* const jArray = dynamic_cast<TJSONArray* const>(AValue);
if(jArray) {
// value is an array
pOut->AppendLine()->Append("[")->AppendLine();
TJSONArrayEnumerator* jArrayEnum = jArray->GetEnumerator();
int i(0);
while(jArrayEnum->MoveNext()) {
if(++i > 1) pOut->Append(",")->AppendLine();
pOut->Append( ToStringPretty(jArrayEnum->Current));
 
}
pOut->AppendLine()->Append("]");
return pOut->ToString();
}
 
TJSONObject* const jObject = dynamic_cast<TJSONObject* const>(AValue);
if(jObject) {
// value is an object (dict)
pOut->AppendLine()->Append("{")->AppendLine();
TJSONPairEnumerator* pEnum = jObject->GetEnumerator();
int i(0);
while(pEnum->MoveNext()) {
if(++i > 1) pOut->Append(",")->AppendLine();
pOut->Append(
pEnum->Current->JsonString->ToString() + ": " +
ToStringPretty(pEnum->Current->JsonValue));
}
pOut->AppendLine()->Append("}");
return pOut->ToString();
}
 
return AValue->ToString();
}
 

Использование с TJSONValue / TJSONObject:
Код
TJSONValue* pJSON = TJSONObject::ParseJSONValue(GJSONString);
String sJSON = Prettify(ToStringPretty(pJSON));
 
Записан
User985
новенький


Сказали спасибо: +0/-0
Offline

Сообщений: 2


« Ответ #8 : 21 Апрель 2015, 22:58:12 »

Доброго времени суток. Раз уж речь зашла о JSON и дабы не плодить темы может кто-нибудь помочь оптимизировать код и/или удалить лишнее? Код рабочий (откопан в инете и переделан под себя), но знаний не хватает, что бы адаптировать его к нынешним возможностям классов (к примеру в TJSONArray теперь не рекомендуется использовать Get, нужно использовать Items)

Цитировать
System.JSON.TJSONArray.Get
....
Warning: Get is deprecated. Please use Items.

Items:
Код:
__property TJSONValue* Items[const int Index] = {read=GetValue};

Работаю в RAD Studio XE8, нужно распарсить ответ vk api, метод video.get.

(Указаны то, что мне нужно, ещё нужен count - идет сразу после response)
Код
#include 
...
TJSONObject* obj( dynamic_cast < TJSONObject*>( TJSONObject::ParseJSONValue( RESTResponse1->Content ) ) );
TJSONObject* rsp = dynamic_cast < TJSONObject*>( object->Get( "response" )->JsonValue );
TJSONArray*  items = dynamic_cast < TJSONArray* >( rsp->Get( "items" )->JsonValue );
TJSONObject* obj2 = dynamic_cast <TJSONObject*>( items->Get(i) );
 
id = obj2->GetValue( "id" )->ToString( );
oid = obj2->GetValue( "owner_id" )->ToString( );
title = obj2->GetValue( "title" )->ToString( );
player = obj2->GetValue( "player" )->ToString( );

Меня беспокоит наличие большого кол-ва TJSONObject. Как я понял просто TJSONObject* obj; дело не кончится и нужны dynamic_cast
RESTResponse кстати тоже умеет работать с JSONValue, но не уверен, что он сумеет разобрать весь массив, а только первую группу (имеется ввиду items:[{id....},{id....}])

Пример ответа АПИ:
Цитировать
response: {
count: 18,
items: [{
id: 123456789,
owner_id: 123456,
title: 'ИТ: Будь в теме!',
duration: 603,
description: '...',
date: 12345678,
views: 666,
comments: 18,
...
player: 'http://www.youtube.com/embed/d....'
}, {
id: 122345467,
owner_id: 12345,
title: '...',
duration: 93,
Спасибо
Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


« Ответ #9 : 22 Апрель 2015, 19:04:22 »

По идее все правильно, структура JSON у тебя такая:

Код
TJSONObject:
 TJSONNumber (count)
 TJSONArray (items):
   TJSONObject:
     TJSONNumber (id)
     TJSONString (title)
     ...
   TJSONObject:
     ...
 
Записан
User985
новенький


Сказали спасибо: +0/-0
Offline

Сообщений: 2


« Ответ #10 : 12 Май 2015, 23:05:29 »

UPD: в рамках компонентов RESTResponse модно сделать (к примеру)так:
Код:
RESTRequest1->Execute();
RESTResponse1->RootElement = "response.items[0]"; //Items - массив содержащий несколько пар элементов.
TJSONValue *val = RESTResponse1->JSONValue;
TJSONArray* arr = (TJSONArray*)val;
ShowMessage(arr->Count);

Или так:
Код:
RESTResponse1->RootElement = "response.items[0].title";
ShowMessage(RESTResponse1->JSONText);
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  




....

Powered by SMF 1.1.21 | SMF © 2025, Simple Machines
Страница сгенерирована за 0.132 секунд. Запросов: 21.