Парсинг JSON
Запрос массива данных в формате JSON
Подобно XML, JSON (JavaScript Object Notation) является протоколом передачи данных. Как следует из названия, этот протокол используют JavaScript, но он гораздо удобнее, чем XML. В настоящее время это наиболее распространенный способ коммуникации в Интернете. Например, если для передачи одного и того же контента использовать два выражения - на XML и JSON, то выражение на базе JSON будет гораздо проще. Ниже приводится такой пример. В этом разделе мы поговорим о парсинге данных в формате JSON.
XML формат - <name>Obama</name><math>50</math>
JSON формат - [name:Obama, math:50]
Создайте новый проект 'JsonParse'. Внесите изменения в файл исходного кода.
#include "jsonparse.h" #include <json-glib/json-glib.h>
json-glib/json-glib.h — это файл заголовка библиотеки парсинга JSON.
Выражения JSON сохраняют массивы в символах '[]'. Мы будем выделять данные из массива одно за другим. Добавьте код выше функции create_base_gui().
static void parse_json(appdata_s *ad) { JsonParser *parser = json_parser_new (); char buf[256]; buf[0] = '\0'; const char* data1 = "[11, 22, 33, 44, 55]"; if( json_parser_load_from_data( parser, data1, strlen(data1), NULL)) { JsonNode *root = json_parser_get_root (parser); JsonArray *temp_array = json_node_get_array ( root ); for(int i=0; i < json_array_get_length(temp_array); i++ ) sprintf(buf, "%s - %d", buf, json_array_get_int_element(temp_array, i)); } elm_object_text_set(ad->label, buf); }
JsonParser — это структура, используемая для парсинга данных в формате JSON.
json_parser_new() - это API, который создает объект JsonParser.
Мы сохранили выражение JSON в строковой переменной с именем data1. Этот массив будет содержать пять числовых значений.
json_parser_load_from_data(JsonParser*, gchar*, gssize, GError**) - это API, который вводит выражение JSON в объект JsonParser. Эти параметры следующие: объект JsonParser, данные JSON, длина данных и код ошибки.
json_parser_get_root(JsonParser*) - это API, который возвращает стартовую позицию объекта JsonParser. Возвращаемый формат - JsonNode.
json_node_get_array(JsonNode*) - это API, который возвращает выражение Json в виде массива. Возвращаемый формат - JsonArray.
json_array_get_length(JsonArray*) - это API, который возвращает количество элементов в массиве Json array. Возвращаемый формат - guint.
json_array_get_int_element(JsonArray*, guint) - это API, который преобразует некоторый элемент массива Json в целое число и возвращая его. Возвращаемый формат - gint64.
При запуске приложения вышеописанная функция запускается автоматически. Добавьте строчку кода в конец функции create_base_gui().
/* Show window after base gui is set up */ evas_object_show(ad>win); parse_json(ad); }
Запустим приложение. В метке отображаются пять фрагментов данных.
Запрос данных с ключом
Обычно, выражения Json используются в следующем формате: имя — это ключ, Обама — это данные.
{name:Obama, math:50}
Далее, мы поговорим о том, как запрашивать данные, используя ключ или значение. Добавьте код в функцию parse_json().
~ const char* data2 = "{'time': '03:53:25 AM', 'millisec_epoch': 1362196405309, 'date': '03-02-2013'}"; if( json_parser_load_from_data( parser, data2, strlen(data2), NULL)) { JsonNode *root = json_parser_get_root (parser); JsonObject *obj = json_node_get_object(root); char* time_data = json_object_get_string_member (obj, "time"); long long epoch_data = json_object_get_int_member (obj, "millisec_epoch"); sprintf(buf, "%s <br/><br/> time - %s <br/> epoch - %lld", buf, time_data, epoch_data); } elm_object_text_set(ad->label, buf); }
Мы сохранили ыражеие Json в строковой переменной data2, и мы также ввели выражение Json в объект JsonParser с помощью функции json_parser_load_from_data().
json_node_get_object(JsonNode*) - это API, который возвращает выражение Json в форме JsonObject.
json_object_get_string_member(JsonObject*, gchar*) - это API, который заставляет объект JsonObject возвращать данные в строковом формате. Использование ключа в качестве второго параметра делает видимыми данные, возвращенные в формате gchar*.
json_object_get_int_member(JsonObject*, gchar*) - это API, который заставляет объект JsonObject возвращать данные в числовом формате. Использование ключа в качестве второго параметра делает видимыми данные, возвращенные в формате gint64.
Запустите пример. На экране отображаются данные времени и эпохи.
Многоуровневый парсинг
Посмотрев на выражение Json, мы можем увидеть, что координата включает в себя объект Json и массив Json. В этом разделе мы поговорим о том, как выполнить парсинг сложного выражения Json, подобного этому.
{'coord':{'lon':127.03, 'lat':37.5}, 'weather':[{'id':800, 'main':'Clear'}, {'id':887, 'main':'Cloudy'}]}
Добавьте код в конце функции parse_json(). Этот код запрашивает данные из объекта Json, включенных в выражение Json.
~ const char* data3 = "{'coord':{'lon':127.03, 'lat':37.5}, 'weather':[{'id':800, 'main':'Clear'}, {'id':887, 'main':'Cloudy'}]}"; if( json_parser_load_from_data( parser, data3, strlen(data3), NULL)) { JsonNode *root = json_parser_get_root (parser); JsonObject *obj = json_node_get_object(root); JsonNode *temp_node = json_object_get_member (obj, "coord"); JsonObject *temp_object = json_node_get_object(temp_node); sprintf(buf, "%s <br/><br/> coord:lon - %0.2f", buf, json_object_get_double_member (temp_object, "lon")); } elm_object_text_set(ad->label, buf);
Мы сохранили выражение Json в строковой переменной data3, и, также, ввели выражение Json в объект JsonParser с помощью функции json_parser_load_from_data().
Мы запросили объект Json node в начальной точке с помощью функции json_parser_get_root() и мы теперь преобразуем выражение Json в объект JsonObject с помощью функции json_node_get_object().
json_object_get_member(JsonObject *, gchar*) - это API, который возвращает некоторый объект JsonObject. Его параметры: объект JsonParser и имя члена. Возвращаемый формат - JsonNode.
Мы запросили объект JsonObject из JsonNode с помощью функции json_node_get_object().
json_object_get_double_member(JsonObject *, gchar*) - это API, который заставляет объект JsonObject возвращать данные в формате действительных чисел. Использование ключа в качестве второго параметра делает видимыми данные, возвращение в формате gdouble.
Запустите пример. На экране отобразятся данные, соответствующие ключу долготы в группе координат
Парсинг данных из внутренней группы массива
В этом разделе мы выполним запрос знамений, соответствующих идентификатору ('id') в первом элементе массива, названным 'weather' в таком же выражении Json. Добавьте код в функцию parse_json().
const char* data3 = "{'coord':{'lon':127.03, 'lat':37.5}, 'weather':[{'id':800, 'main':'Clear'}, {'id':887, 'main':'Cloudy'}]}"; if( json_parser_load_from_data( parser, data3, strlen(data3), NULL)) { JsonNode *root = json_parser_get_root (parser); JsonObject *obj = json_node_get_object(root); JsonNode *temp_node = json_object_get_member (obj, "coord"); JsonObject *temp_object = json_node_get_object(temp_node); sprintf(buf, "%s <br/><br/> coord:lon - %0.2f", buf, json_object_get_double_member (temp_object, "lon")); temp_node = json_object_get_member ( obj,"weather" ); JsonArray *temp_array = json_node_get_array ( temp_node ); temp_node = json_array_get_element(temp_array, 0 ); temp_object = json_node_get_object( temp_node ); sprintf(buf, "%s <br/> weather:id - %d", buf, json_object_get_int_member(temp_object, "id")); } elm_object_text_set(ad->label, buf);
Запрос узла массива, названного 'weather' с помощью функции json_object_get_member() и преобразование узла массива в форму JsonArray с помощью функции json_node_get_array().
Запрос узла для первого элемента с помощью функции json_array_get_element() и преобразование в форму JsonObject с помощью функции json_node_get_object().
В заключение, преобразование данных, соответствующих ключу с именем 'id' в целое число с помощью функции json_object_get_int_member().
Запустите пример. На экране отобразится значение, соответствующее 'id' первого элемента массива.