Загрузка JSON в дерево значений

29.06.21

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

Читаем и парсим JSON, засовываем его в дерево - что тут сложного?

Скачать файлы

Наименование Файл Версия Размер
Загрузка JSON в дерево значений:
.epf 7,05Kb
8
.epf 0.1 7,05Kb 8 Скачать

JSON -> ДЕРЕВО ЗНАЧЕНИЙ

 

ВВЕДЕНИЕ

Некоторые уже стали забывать, а некоторые даже и не знали (вот я, например), что JSON - это JavaScript Object Notation, что переводится примерно как "'Запись' объекта в JavaScript". Честно говоря, слово "нотация" вроде как можно и не переводить - оно уже входит в русский язык, но в данном случае это именно "запись", т.е. представление объекта в виде некой структурированной записи - структуры данных, а в данном конкретном случае еще и характерная для JavaScript.

Сейчас JSON используется далеко за пределами JS, парсеры для JSON появились даже в 1С и представляют из себя мало отличимый от персера XML список объектов для повседневного использования.

 

ПАРСЕР JSON В 1С 

Здесь, как и в XML, есть два простых базовых объекта для чтения и записи JSON. Вот они:

Запись = Новый ЗаписьJSON;
Чтение = Новый ЧтениеJSON;

 Собственно, работа с этими объектами в обычном повседневном применении проста до безобразия:

// Читаем JSON

Чтение.УстановитьСтроку( СтрокаJSON ); // строка, которая прилетела к вам из какого-нибудь сервиса
ДанныеСтруктура = ПрочитатьJSON( Чтение);
ДанныеСоответствие = ПрочитатьJSON( Чтение, Истина );

// Пишем JSON

Запись.УстановитьСтроку();
ЗаписатьJSON( Запись, ДанныеСтруктура ); // значением может быть простой тип, структура и соответствие
СтрокаJSON = Запись.Закрыть();

JSON в 1С может быть прочитан в структуру или соответствие ("Истина" во втором параметре как раз говорит, чтобы система прочитала данные в соответствие). Также если в данных есть даты, то имена этих полей нужно указать в следующем параметре. Там есть еще некоторое количество параметров, которые могут пригодиться вам, если вдруг вы захотите записать что-то помимо простых типов, массивов, структур, соответствий и их фиксированных вариантов.

При записи JSON может быть преобразован простой тип, структура, соответствие, дата и т.д. = здесь уже не надо заморачиваться со списком полей и видом преобразование. А если вы хотите записать что-то помимо этого, то, опять же, вам помогут дополнительные параметры с указанием функции преобразования.

Надеюсь, что с чтением и записью мы разобрались. Давайте превратим этот набор данных в дерево. Т.е. мы сделаем дерево из структуры (кто хочет - может сделать дерево и из соответствия - даже код менять не нужно).

 

В ДЕРЕВО!

Ну код тут прост, как три копейки...

&НаСервере
Процедура ПоместитьВДерево( Текст )
	Чтение = Новый ЧтениеJSON;
	Чтение.УстановитьСтроку( Текст );
	Данные = ПрочитатьJSON( Чтение );
	
	ЗначениеВРеквизитФормы(
		РазвернутьВДерево( РеквизитФормыВЗначение("Дерево"), Данные ),
		"Дерево" );
	
КонецПроцедуры
	
&НаСервереБезКонтекста
Функция РазвернутьВДерево( Дерево, Данные, Параметр = "" )
	Для Каждого Ст ИЗ Данные Цикл 
		Если ТипЗнч(Ст) = Тип("КлючИЗначение") Тогда 
			Строка = Дерево.Строки.Добавить();
			Строка.Параметр = Ст.Ключ;
			Если ТипЗнч(Ст.Значение) = Тип("Структура") 
				ИЛИ ТипЗнч(Ст.Значение) = Тип("Массив") Тогда 
				РазвернутьВДерево( Строка, Ст.Значение, Ст.Ключ );
			Иначе
				Строка.Значение =  Ст.Значение
			КонецЕсли;
		Иначе
			Строка = Дерево.Строки.Добавить();
			Строка.Параметр = Параметр;
			Если ТипЗнч(Ст) = Тип("Структура") 
				ИЛИ ТипЗнч(Ст) = Тип("Массив") Тогда 
				РазвернутьВДерево( Строка, Ст, Параметр );
			Иначе
				Строка.Значение =  Ст
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	Возврат Дерево
КонецФункции

На выходе у нас что-то типа этого:

Исходный файл вот такой (начало):

{"dox":{"tux":{"res":[{
"part":{"xtd":"320565","godex":{"name":"TE Connectivity"},
"ibo":[{
"hado":{"name":"oxford"},"hubos":[{
[...]

В общем, пробуйте, уважаемые господа-товарищи - обработка прикреплена.

PS: в справке 1С написано, что данный функционал доступен с 8.3.6, но тестировалась обработка на 8.3.18.1289.

JSON парсинг дерево значений

См. также

Печать любых непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

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

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

3480 руб.

22.08.2023    788    1    0    

1

Валидация JSON через XDTO (включая массивы)

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

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

28.08.2023    3032    YA_418728146    3    

84

Загрузка файлов json в дерево значений

Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Обработка грузит файлы формата JSON в дерево значений формы.

2 стартмани

03.04.2023    1695    0    IVC_goal    6    

6

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

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

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

1 стартмани

13.10.2022    13189    100    sapervodichka    106    

118

Система контроля ведения учета [БСП]

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

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    6313    quazare    8    

103

Хитрости СКД. Часть 3

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

Столкнулся с тем, что мне приходится писать гору отчетов. Во многих приходится использовать повторяющиеся приемы. Решил написать шпаргалку, которая, надеюсь пригодится не только мне. В этой статье: Объединение ячеек в отчете только на определенном уровне иерархии, Постобработка итогов в табличном документе, Скрытие колонок в зависимости от количества месяцев в периоде.

28.05.2022    7654    milkers    11    

87
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. aleksey2 83 30.06.21 08:15 Сейчас в теме
начиная с платформы 8.3.6.1977
2. ITSun 28.07.21 08:23 Сейчас в теме
Тренируетесь?

Физкультура - это хорошо!
И рейтинг опять же.
3. starik-2005 2871 28.07.21 11:53 Сейчас в теме
(2)
Тренируетесь
Типа того. Реакция на одного неадеквата в действительности.
4. RustIG 1728 02.12.21 00:57 Сейчас в теме
5. RustIG 1728 02.12.21 01:13 Сейчас в теме
кажется дерево содержит лишние узлы - см. картинку
Прикрепленные файлы:
7. starik-2005 2871 02.12.21 23:30 Сейчас в теме
(5) так было надо.
6. RustIG 1728 02.12.21 14:13 Сейчас в теме
создание дерева через рекурсию
Процедура СоздатьДерево(Кнопка)
	
	Чтение = Новый ЧтениеJSON;
	Чтение.УстановитьСтроку(ЭлементыФормы.ПолеТекстовогоДокумента1.ПолучитьТекст());
	Данные = ПрочитатьJSON(Чтение);
	
	Дерево = Новый ДеревоЗначений;
	Дерево.Колонки.Добавить("Параметр");
	Дерево.Колонки.Добавить("Значение");
	
	ТекУзел = Дерево;
		
	ДобавитьУзел(ТекУзел, Данные);
	
	ЭлементыФормы.Дерево.СоздатьКолонки();	

КонецПроцедуры

Процедура ДобавитьУзел(ТекУзел, СтруктураДерева)
		
	Для Каждого ЭлСтруктуры Из СтруктураДерева Цикл
		
		Если ТипЗнч(СтруктураДерева)=Тип("Структура") Тогда			
 
			ПодчиненныйУзел = ТекУзел.Строки.Добавить();
			ПодчиненныйУзел.Параметр = ЭлСтруктуры.Ключ;
			
			Если ТипЗнч(ЭлСтруктуры.Значение)=Тип("Структура") 
				ИЛИ ТипЗнч(ЭлСтруктуры.Значение)=Тип("Массив") Тогда
				ДобавитьУзел(ПодчиненныйУзел, ЭлСтруктуры.Значение);
			Иначе
				ПодчиненныйУзел.Значение = ЭлСтруктуры.Значение;
			КонецЕсли; 		
			
		Иначе //массив
			
			//ПодчиненныйУзел = ТекУзел.Строки.Добавить();
			//ПодчиненныйУзел.Параметр = ЭлСтруктуры;
			
			Если ТипЗнч(ЭлСтруктуры)=Тип("Структура") 
				ИЛИ ТипЗнч(ЭлСтруктуры)=Тип("Массив") Тогда
				ДобавитьУзел(ТекУзел, ЭлСтруктуры);
			Иначе
				ПодчиненныйУзел.Значение = ЭлСтруктуры;
			КонецЕсли; 		
			
		КонецЕсли;
			
	КонецЦикла;
		
КонецПроцедуры
Показать
Прикрепленные файлы:
8. miXna5 72 06.12.21 17:08 Сейчас в теме
(6) У вас добавляются только узлы 1 уровня. Если подчиненность идет дальше, будет выводиться неверно (без вложенности). У автора поста отрабатывает нормально.
9. RustIG 1728 06.12.21 18:33 Сейчас в теме
(8) а где пример?
10. miXna5 72 20.12.21 14:25 Сейчас в теме
(9) Вот пример. На прикрепленных скриншотах результат выполнения по методу автора и по вашему.
По методу автора массив элементов, которые состоят в свою очередь из объектов разложится наглядно в структуры, а по вашей процедуре свойства объектов в массиве будут выводится общим списком, что не наглядно.
Дело как раз в двух закомментированных строках.
Прикрепленные файлы:
11. RustIG 1728 20.12.21 15:08 Сейчас в теме
(10) можете прислать файл json? хочу сам отладить
12. miXna5 72 20.12.21 16:16 Сейчас в теме
(11) Мне это API портала "Электронный знак" (Белорусский аналог Честного знака) возвращает. Сохранил в файл.
Прикрепленные файлы:
Пример.json
13. RustIG 1728 20.12.21 18:13 Сейчас в теме
(12) спасибо.
разобрался.
моей целью было - как можно точнее отобразить содержимое файла джейсон
вот сравните результат моего алгоритма и содержимое файла джейсон
Прикрепленные файлы:
14. RustIG 1728 20.12.21 18:24 Сейчас в теме
(12) один файл джейсон можно сгенерировать несколькими алгоритмами, при этом несколько по-разному связанных таблиц в базе данных можно отобразить одним и тем же файлом джейсон.... файл джейсон призван передать в сжатом виде информацию только в одну сторону. Каким образом расшифровывать полученный файл - это уже задача интерпретатора, и можно использовать как алгоритм Сергея Андреева, так и мой вариант. В его алгоритме надо "держать в уме" что повторяющиеся узлы "params" - это не элемент структуры, а очередной элемент списка (!)...
В моем варианте нужно "держать в уме" что повторяющиеся элементы списка не обрамлены структурно в узлы, а идут последовательно друг за другом....
Это как расшифровка xml-файла - алгоритм расшифровки всегда уникален и индивидуален.
Вообще,я думаю, можно найти золотую середину - компромисс - использовать алгоритм варианта 3 (!) - мы структурно выделяем элементы списка, но в названии узла используем префикс или суффикс - отличающий наш "1с-овский" узел - например "params1","params2", "params3", "держа в уме" что одноименные параметры - это всегда элементы списка, а номер параметра это порядковый номер...
15. RustIG 1728 20.12.21 18:45 Сейчас в теме
(12) или еще вариант - мы все привыкли что для отображения джейсон -структуры можно использовать Дерево с двумя полями (!):
 Дерево = Новый ДеревоЗначений;
	Дерево.Колонки.Добавить("Параметр");
	Дерево.Колонки.Добавить("Значение");

Я предлагаю использовать три поля - добавить еще "ТипЭлемента": значениями будут "УзелСтруктуры" или "ЭлементСписка" ("ЭлементМассива"):

 Дерево = Новый ДеревоЗначений;
	Дерево.Колонки.Добавить("Параметр");
	Дерево.Колонки.Добавить("Значение");
       Дерево.Колонки.Добавить("ТипЭлемента");

Это для моего варианта алгоритма и для варианта Сергея Андреева - будет полезно, чтобы была однозначная интерпретация.
16. RustIG 1728 20.12.21 18:49 Сейчас в теме
(12) в целом , спасибо за активное участие! я для себя понял гораздо больше нюансов джейсон-структур.
17. RustIG 1728 20.12.21 19:33 Сейчас в теме
(12) готово!
вот код:
Процедура СоздатьДерево(Кнопка)
	
	Чтение = Новый ЧтениеJSON;
	Чтение.УстановитьСтроку(ЭлементыФормы.ПолеТекстовогоДокумента1.ПолучитьТекст());
	Данные = ПрочитатьJSON(Чтение);
	
	//Для Каждого Ст ИЗ Данные Цикл 
	//	Если ТипЗнч(Ст) = Тип("КлючИЗначение") Тогда 
	//		Строка = Дерево.Строки.Добавить();
	//		Строка.Параметр = Ст.Ключ;
	//		Если ТипЗнч(Ст.Значение) = Тип("Структура") 
	//			ИЛИ ТипЗнч(Ст.Значение) = Тип("Массив") Тогда 
	//			РазвернутьВДерево( Строка, Ст.Значение, Ст.Ключ );
	//		Иначе
	//			Строка.Значение =  Ст.Значение
	//		КонецЕсли;
	//	Иначе
	//		Строка = Дерево.Строки.Добавить();
	//		Строка.Параметр = Параметр;
	//		Если ТипЗнч(Ст) = Тип("Структура") 
	//			ИЛИ ТипЗнч(Ст) = Тип("Массив") Тогда 
	//			РазвернутьВДерево( Строка, Ст, Параметр );
	//		Иначе
	//			Строка.Значение =  Ст
	//		КонецЕсли;
	//	КонецЕсли;
	//КонецЦикла;	

	Дерево = Новый ДеревоЗначений;
	Дерево.Колонки.Добавить("Параметр");
	Дерево.Колонки.Добавить("Значение");
	Дерево.Колонки.Добавить("ТипЭлемента");
	
	ТекУзел = Дерево;
		
	ДобавитьУзел(ТекУзел, Данные);
	
	ЭлементыФормы.Дерево.СоздатьКолонки();	

КонецПроцедуры

Процедура ДобавитьУзел(ТекУзел, СтруктураДерева, ТипЭлемента = "")
		
	Для Каждого ЭлСтруктуры Из СтруктураДерева Цикл
		
		Если ТипЗнч(СтруктураДерева)=Тип("Структура") Тогда			
			
			ТипЭлемента = ТипЗнч(ЭлСтруктуры.Значение);
			
			ПодчиненныйУзел = ТекУзел.Строки.Добавить();
			ПодчиненныйУзел.Параметр = ЭлСтруктуры.Ключ;
			ПодчиненныйУзел.ТипЭлемента = ТипЭлемента;
			
			Если ТипЭлемента=Тип("Структура") ИЛИ ТипЭлемента=Тип("Массив") Тогда
				ДобавитьУзел(ПодчиненныйУзел, ЭлСтруктуры.Значение, ТипЭлемента);
			Иначе
				ПодчиненныйУзел.Значение = ЭлСтруктуры.Значение;
			КонецЕсли; 		
			
		Иначе //массив
			
			ТипЭлемента = ТипЗнч(ЭлСтруктуры);
			
			ПодчиненныйУзел = ТекУзел.Строки.Добавить();
			ПодчиненныйУзел.Параметр = "" + ЭлСтруктуры + СтруктураДерева.Найти(ЭлСтруктуры);
			ПодчиненныйУзел.ТипЭлемента = ТипЭлемента;    			

			Если ТипЭлемента=Тип("Структура") ИЛИ ТипЭлемента=Тип("Массив") Тогда
				ДобавитьУзел(ТекУзел, ЭлСтруктуры, ТипЭлемента);
			Иначе
				ПодчиненныйУзел.Значение = ЭлСтруктуры;
				ПодчиненныйУзел.ТипЭлемента = ТипЭлемента;
			КонецЕсли; 		
			
		КонецЕсли;
			
	КонецЦикла;
		
КонецПроцедуры

Показать


результат в картинках
Прикрепленные файлы:
Оставьте свое сообщение