Разбор любого JSON-объекта в соответствующую структуру

13.11.19

Разработка - Универсальные функции

Данная публикация предназначена разработчикам 1С, которым приходиться разбирать данные формата JSON. Выложенный пример кода создает объект типа Структура, полностью повторяющий структуру данных формата JSON.

Всех приветствую!

 

Прилагаю несколько функций, которые могут пригодиться другим разработчикам 1С для разбора JSON-объектов и конвертации их в соответствующие структуры:

1. Создаем объект ЧтениеJSON на основе текста объекта:

Функция фПрочитатьJSON(ТекстJSON) Экспорт
	Чтение = Новый ЧтениеJSON;
	Чтение.УстановитьСтроку(ТекстJSON);
	Структура = ЗаполнитьСтруктуруИзОтветаJSON(Чтение);	
	Чтение.Закрыть();
	Возврат Структура;
КонецФункции

2. Рекурсивная процедура  для возврата объекта типа Структура

Функция ЗаполнитьСтруктуруИзОтветаJSON(Знач Чтение) Экспорт
	Результат = Новый Структура;

	ПоследнееИмяРеквизита = Неопределено;
	
	Пока Чтение.Прочитать() Цикл
		Тип = Чтение.ТипТекущегоЗначения;
		Если Тип = ТипЗначенияJSON.НачалоОбъекта И ПоследнееИмяРеквизита<>Неопределено Тогда 
			Результат[ПоследнееИмяРеквизита] = ЗаполнитьСтруктуруИзОтветаJSON(Чтение);
		ИначеЕсли Тип = ТипЗначенияJSON.КонецОбъекта Тогда 
			Возврат Результат;
			ПоследнееИмяРеквизита = Неопределено;
		ИначеЕсли Тип = ТипЗначенияJSON.ИмяСвойства Тогда 
			Результат.Вставить(Чтение.ТекущееЗначение, Неопределено);
			ПоследнееИмяРеквизита = Чтение.ТекущееЗначение;
		ИначеЕсли Тип = ТипЗначенияJSON.Булево или Тип = ТипЗначенияJSON.Строка
			или Тип = ТипЗначенияJSON.Число или Тип = ТипЗначенияJSON.Null Тогда 
			Результат[ПоследнееИмяРеквизита] = Чтение.ТекущееЗначение;
		ИначеЕсли Тип = ТипЗначенияJSON.НачалоМассива Тогда 
			Результат[ПоследнееИмяРеквизита] = ЗаполнитьМассивИзОтветаJSON(Чтение);
		КонецЕсли;
	КонецЦикла;  
		
	Возврат Результат;
КонецФункции 

3. В случае использования массивов в JSON-объекте используем третью процедуру

Функция ЗаполнитьМассивИзОтветаJSON(Знач Чтение)
	Результат = Новый Массив;
	
	Пока Чтение.Прочитать() Цикл
		Тип = Чтение.ТипТекущегоЗначения;
		Если Тип = ТипЗначенияJSON.НачалоОбъекта Тогда 
			Результат.Добавить(ЗаполнитьСтруктуруИзОтветаJSON(Чтение));
		ИначеЕсли Тип = ТипЗначенияJSON.КонецМассива Тогда 
			Возврат Результат;
		КонецЕсли;
	КонецЦикла;  
	
	Возврат Результат;
КонецФункции

Вот и все! Всем хорошего времени суток!

импорт JSON чтение Структура

См. также

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Благодаря этим пяти строчкам можно больше не заморачиваться с загрузкой из внешних файлов. Пользуюсь везде, всегда и постоянно.

21.05.2024    20251    dimanich70    81    

145

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    4100    3    John_d    11    

57

Универсальные функции Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    18213    atdonya    24    

57

Универсальные функции Программист Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    5511    ke.92@mail.ru    16    

65

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    14779    YA_418728146    7    

166

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    3596    57    progmaster    8    

4

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    18500    171    sapervodichka    112    

135
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. dock 44 13.11.19 16:40 Сейчас в теме
В чем отличие от платформенной ?

Глобальный контекст (Global context)
ПрочитатьJSON (ReadJSON)
Синтаксис:
ПрочитатьJSON(<ЧтениеJSON>, <ПрочитатьВСоответствие>, <ИменаСвойствСоЗначениямиДата>, <ОжидаемыйФорматДаты>, <ИмяФункцииВосстановления>, <МодульФункцииВосстановления>, <ДополнительныеПараметрыФункцииВосстановления>, <ИменаСвойствДляОбработкиВосстановления>, <МаксимальнаяВложенность>)


Примечание:

Массив будет десериализован в массив. Объект JSON будет преобразован в соответствие или структуру (если ключ структуры окажется недопустимым, будет вызвано исключение).
Для дат действует аналогично методу ПрочитатьДатуJSON.
Во время выполнения метода может быть вызвана пользовательская функция для восстановления значения - для этого следует использовать параметр <ИмяФункцииВосстановления>. Функция восстановления должна быть описана с директивой &НаСервере или &НаКлиенте. Использование функции вне контекста не допускается.
spenser123; GV.; bambucho; nekit_rdx; de0nis; zakiap; philya; agentz; +8 Ответить
2. VmvLer 13.11.19 16:42 Сейчас в теме
(1) в том, что автор не читает СП
3. DJDUH 17 13.11.19 17:23 Сейчас в теме
И, что даже такой кусочек прочтёт?
{
  "name": "Иван",
  "age": 30,
  "isAdmin": false,
  "1": 1,
  "2": 2,
  "3": 3
}

// Или

{
  "ФИО": "Иванов Иван Иванович",
  "возраст": 30,
  "Админ": false,
  "Контакты":[  
{       "1": 1111111,
  "2": "222-22-22",
  "3": 3333333}]
}


Показать
Артано; +1 Ответить
5. zavladaev 485 13.11.19 17:36 Сейчас в теме
(3) Прочитает в соответствие.
Но такой "кусочек" вышеописанная функция не прочитает.
7. dock 44 13.11.19 22:01 Сейчас в теме
(3)
Не прочитает, само собой.
Да и опубликованная обработка не прочитает.
Ошибка будет:
Недопустимое имя свойства: '1' для чтения JSON в объект Структура

И это не ошибка JSON - приведенные примеры валидны.
Это ограничения типа "структура":
Структура (Structure)
Элементы коллекции:
КлючИЗначение
Описание:
Представляет собой коллекцию пар КлючИЗначение. При этом ключ может быть только строковым и должен удовлетворять требованиям, предъявляемым к именованию переменных встроенного языка.
tuzmich007; bambucho; user675510_Wealpe; HAMAZ; Артано; +5 Ответить
4. Eugen-S 406 13.11.19 17:31 Сейчас в теме
Пример использования "ПрочитатьJSON":

ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(ТекстJSON);
Структура = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();


Или

ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.ОткрытьФайл(ФайлJSON,"UTF-8");
Структура = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Prad2002; nekit_rdx; bambucho; shevchen88; ulen; +5 Ответить
15. bambucho 18.11.22 12:20 Сейчас в теме
(4)Такой способ прочитает вложенную коллекцию/массив в JSONе? - если такое возможно правда в рамках JSON-данных...
6. Поручик 4692 13.11.19 18:54 Сейчас в теме
Только я один вытаращил глаза? А как же штатная ПрочитатьJSON? Читает всё, что хочешь, было бы что читать.
Izumov; Romario_; de0nis; Ibrogim; manlak; SagittariusA; Drivingblind; user834484; awk; Lapitskiy; Shmell; Артано; +12 Ответить
18. d.zhukov 1475 14.06.24 04:48 Сейчас в теме
8. Lapitskiy 1061 14.11.19 07:43 Сейчас в теме
Может это для 8.2 ? Там встроенных средств не было..
9. lmnlmn 69 14.11.19 09:52 Сейчас в теме
10. andy_zhav 197 14.11.19 11:37 Сейчас в теме
Вот такой код разбирает JSON любой вложенности
Функция РазобратьJSON(Данные)
	Структура = Новый Структура;
	Свойство = Неопределено;
	Значение = Неопределено;
	ЧтениеJSON = Новый ЧтениеJSON;
	ЧтениеJSON.УстановитьСтроку(Данные);
	Пока ЧтениеJson.Прочитать() Цикл
		ТипJson = ЧтениеJson.ТипТекущегоЗначения;
		Если ТипJSON = ТипЗначенияJSON.Число Или ТипJson = ТипЗначенияJSON.Строка Или
			ТипJson = ТипЗначенияJSON.Булево Или ТипJson = ТипЗначенияJSON.Null Тогда
			Значение = ЧтениеJson.ТекущееЗначение;
			Если Свойство = "GUID" Тогда
				Значение = ПреобразоватьВGUID(Значение);
			КонецЕсли;
			Структура.Вставить(Свойство, Значение);
			//Массив.Добавить(Структура);
		ИначеЕсли ТипJson = ТипЗначенияJSON.ИмяСвойства Тогда 
			//Структура.Вставить(Свойство);
			Свойство = ЧтениеJson.ТекущееЗначение;
		КонецЕсли;
	КонецЦикла;
	Возврат Структура;
КонецФункции

Процедура РазобратьJSONРекурсия(ЧтениеJSON, Дерево)
    
    ИмяСвойства = Неопределено;
    
    Пока ЧтениеJSON.Прочитать() Цикл
        TипJSON = ЧтениеJSON.ТипТекущегоЗначения;
        
        Если TипJSON = ТипЗначенияJSON.НачалоОбъекта 
        ИЛИ TипJSON = ТипЗначенияJSON.НачалоМассива Тогда
            НовыйОбъект = ?(TипJSON = ТипЗначенияJSON.НачалоОбъекта, Новый Структура, Новый Массив);
            
            Если ТипЗнч(Дерево) = Тип("Массив") Тогда
                Дерево.Добавить(НовыйОбъект);
            ИначеЕсли ТипЗнч(Дерево) = Тип("Структура") И ЗначениеЗаполнено(ИмяСвойства) Тогда
                Дерево.Вставить(ИмяСвойства, НовыйОбъект);
            КонецЕсли;
            
            РазобратьJSONРекурсия(ЧтениеJSON, НовыйОбъект);
            
            Если Дерево = Неопределено Тогда
                Дерево = НовыйОбъект;
            КонецЕсли;
        ИначеЕсли TипJSON = ТипЗначенияJSON.ИмяСвойства Тогда
            ИмяСвойства = ЧтениеJSON.ТекущееЗначение;
        ИначеЕсли TипJSON = ТипЗначенияJSON.Число 
        ИЛИ TипJSON = ТипЗначенияJSON.Строка 
        ИЛИ TипJSON = ТипЗначенияJSON.Булево 
        ИЛИ TипJSON = ТипЗначенияJSON.Null Тогда
            Если ТипЗнч(Дерево) = Тип("Массив") Тогда
                Дерево.Добавить(ЧтениеJSON.ТекущееЗначение);
            ИначеЕсли ТипЗнч(Дерево) = Тип("Структура") Тогда
                Дерево.Вставить(ИмяСвойства, ЧтениеJSON.ТекущееЗначение);
            КонецЕсли;
        Иначе
            Возврат;
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры
Показать
11. andy_zhav 197 14.11.19 11:38 Сейчас в теме
Но имена ключей все-таки лучше с символов начинать
14. HAMAZ 7 12.01.20 18:44 Сейчас в теме
(11)конечно лучше. Вот только куча сервисов отвечает JSON'ом в котором имена ключей это UUID'ды.
12. capitan 2507 14.11.19 14:54 Сейчас в теме
РаботаВМоделиСервисаБТС.СтруктураИзСтрокиJSON
13. Cifer 157 14.11.19 17:26 Сейчас в теме
стандартный метод ПрочитатьJSON позволяет прочитать и в структуру и в соответствие.
axelerleo; +1 Ответить
16. bambucho 18.11.22 12:23 Сейчас в теме
(13)еще не ковырял...Вам не сложно дать ссылку или простой пример?
Если в JSON-данных будет вложенная коллекция/массив - спосб "ПрочитатьJSON" справится?
17. mbfg@tut.by 6 16.04.24 14:09 Сейчас в теме
Хоть есть и стандартный метод, но всё равно плюсую.
Оставьте свое сообщение