JSON парсер для 1С, облегченный

05.12.14

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

Простенький парсер JSON для 1С.

Поскольку доступный в сети парсер для меня оказался тяжеловат+ требовал встраивания в конфигурацию, я решил написать свою версию. Здесь представлен вариант работы с Таблицей Значений для наглядности, хотя мне удобнее работать с объектами XDTO.  Для парсинга строки по итогам работы нам нужно знать только позицию и вес(длину)  подстроки объкта, что позволяет легко и быстро организовать доступ к объекту, даже не зная его содержания. "Типобъекта" и "родитель" позволяют строить дерево объектов в xdto.

 

 

Сейчас работаю через парсер со smartsheet.api, ошибок пока не было, но в любом случае, если используете парсер, то делаете это на свой страх и риск %)

&НаСервере
Функция ВернутьСтрокуОбъекта(ПервыйСимвол,ПоследнийСимвол,СтрокаРеквизита)
	 КоличествоВложений=1;
	 СтрокаНабора="";
	 Для к=2 По СтрДлина(СтрокаРеквизита) Цикл
		Символ=Сред(СтрокаРеквизита,к,1);
		Если Символ=ПервыйСимвол ТОгда
			КоличествоВложений=КоличествоВложений+1;
		ИначеЕсли ПоследнийСимвол=Символ Тогда
			КоличествоВложений=КоличествоВложений-1;
		Конецесли;
		Если КоличествоВложений=0 Тогда
			Возврат СтрокаНабора;
		КонецЕсли;
		СтрокаНабора=СтрокаНабора+Символ;
	КонецЦикла;
КонецФункции	

&НаСервере
Процедура ПолучитьСтруктуруСтроки(ТаблицаОбъектов=Неопределено,СтрокаРеквизита,Родитель="",ТипРодителя=2,Позиция=1);
	Если ТаблицаОбъектов=Неопределено Тогда
		ТаблицаОБъектов=Новый ТаблицаЗначений;
		ТаблицаОбъектов.Колонки.Добавить("Имя",Новый ОписаниеТипов("Строка"));
		ТаблицаОбъектов.Колонки.Добавить("ТипОбъекта",Новый ОписаниеТипов("Число"));//0-объект,1-массив,2-прочий;
		ТаблицаОбъектов.Колонки.Добавить("ПозицияВСтроке",Новый ОписаниеТипов("Число")); //позиция в строкеJSON
		ТаблицаОбъектов.Колонки.Добавить("Вес",Новый ОписаниеТипов("Число")); //длина объекта
		ТаблицаОбъектов.Колонки.Добавить("Родитель",Новый ОписаниеТипов("Строка"));//имя родителя
		ТаблицаОбъектов.Колонки.Добавить("Состав",Новый ОписаниеТипов("Строка"));//текстовое содержание объекта
	КонецЕсли;
	ОбъектНайден=0;
	ЭтоИмя=Ложь;
	СтрокаОбъекта=Неопределено;
	СчитаемВеса=Ложь;
	ИмяРеквизита="";
	Вес=0;
	Для к=1 По СтрДлина(СтрокаРеквизита) Цикл
		Символ=Сред(СтрокаРеквизита,к,1);
		ВторойСимвол=Сред(СтрокаРеквизита,к+1,1);
		Если Символ="\" Тогда     //для спецсимволов (их пропускаем, нормализовать текст можно потом)
			к=к+1;
			Если СчитаемВеса ТОгда
				Вес=Вес+2;
			КонецЕсли;	
			Продолжить;
		Конецесли;	
		Если СчитаемВеса ТОгда
			Если Найти(""",]}",Символ)=0 Тогда
				Вес=Вес+1;
			Конецесли;
		КонецЕсли;	
		Если Найти(",]}",Символ)>0 Или к=СтрДлина(СтрокаРеквизита) Тогда
			Если СтрокаОбъекта<>Неопределено Тогда
				СтрокаОбъекта.Вес=Вес;
				СтрокаОбъекта.Состав=Сред(СтрокаРеквизита,СтрокаОбъекта.ПозицияВСтроке-Позиция+1,Вес); //для наглядности
			КонецЕсли;
			ЭтоИмя=Ложь;
			СчитаемВеса=Ложь;
			Вес=0;
			СтрокаОбъекта=Неопределено;
			ИмяРеквизита="";
			Продолжить;
		КонецЕсли;			
		
		Если Символ="""" и Не СчитаемВеса И ТипРодителя<>1 Тогда
			ЭтоИмя=Не ЭтоИмя;
		КонецеСли;	
			
		Если Не ЭтоИмя И Не СчитаемВеса И СтрокаОбъекта=Неопределено Тогда  //Имя реквизита нашли, инвертировали признак имени, создаем реквизит
			Вес=0;
			СтрокаОбъекта=ТаблицаОбъектов.Добавить();
			Если ИмяРеквизита="" Тогда
				ИмяРеквизита=Строка(Новый УникальныйИдентификатор);
			Конецесли;	
			СтрокаОбъекта.Имя=ИмяРеквизита;
			СтрокаОбъекта.Родитель=Родитель;
			СтрокаОбъекта.ТипОбъекта=2;
			ИмяРеквизита="";
		ИначеЕсли ЭтоИмя и Не СчитаемВеса Тогда
			Если Символ<>"""" Тогда
				ИмяРеквизита=ИмяРеквизита+Символ;
			Конецесли;
		КонецЕсли;	
		
		Если Символ=":" Или (ТипРодителя=1 и Символ="""") Тогда
			СчитаемВеса=Истина;
			Если СтрокаОбъекта<>Неопределено Тогда
				Если ВторойСимвол="""" Тогда
					СтрокаОбъекта.ПозицияВстроке=Позиция+к+1;
				Иначе	
					СтрокаОбъекта.ПозицияВстроке=Позиция+к;
				Конецесли;
			КонецЕсли;	
		КонецЕсли;		
		
		Если Символ="{" Тогда      //обрабатываем вложенные объекты
			ВложеннаяСтрока=ВернутьСтрокуОбъекта("{","}",Прав(СтрокаРеквизита,СтрДлина(СтрокаРеквизита)-к+1));
			Если СтрокаОбъекта<>Неопределено Тогда
				СтрокаОбъекта.ПозицияВстроке=Позиция+к;
				СтрокаОбъекта.Состав=ВложеннаяСтрока;
				СтрокаОбъекта.ТипОбъекта=0;
				СтрокаОбъекта.Вес=СтрДлина(ВложеннаяСтрока);
				ПолучитьСтруктуруСтроки(ТаблицаОбъектов,ВложеннаяСтрока,СтрокаОбъекта.Имя,0,СтрокаОбъекта.ПозицияВстроке);
				СчитаемВеса=Ложь;
				СтрокаОбъекта=Неопределено;
				Вес=0;
			Иначе
				ПолучитьСтруктуруСтроки(ТаблицаОбъектов,ВложеннаяСтрока,,Позиция+к);
			КонецЕсли;	
			к=к+СтрДлина(ВложеннаяСтрока)+1;
		КонецЕсли;	
		
		Если Символ="[" Тогда  //обрабатываем вложенные массивы
			ВложеннаяСтрока=ВернутьСтрокуОбъекта("[","]",Прав(СтрокаРеквизита,СтрДлина(СтрокаРеквизита)-к+1));
			Если СтрокаОбъекта<>Неопределено Тогда
				СтрокаОбъекта.ПозицияВстроке=Позиция+к;
				СтрокаОбъекта.Состав=ВложеннаяСтрока;
				СтрокаОбъекта.ТипОбъекта=1;
				СтрокаОбъекта.Вес=СтрДлина(ВложеннаяСтрока);
				ПолучитьСтруктуруСтроки(ТаблицаОбъектов,ВложеннаяСтрока,СтрокаОбъекта.Имя,1,СтрокаОбъекта.ПозицияВстроке);
				СчитаемВеса=Ложь;
				СтрокаОбъекта=Неопределено;
				Вес=0;
			Иначе	
				ПолучитьСтруктуруСтроки(ТаблицаОбъектов,ВложеннаяСтрока,,Позиция+к);
			КонецЕсли;
			к=к+СтрДлина(ВложеннаяСтрока)+1;
		КонецЕсли;			
	КонецЦикла;	
КонецПроцедуры	

Использование: Вызываем процедуру

ПолучитьСтруктуруСтроки(ТаблицаОбъектов,СтрокаJSON);



ТаблицаОбъектов-  пустая таблица значений в которую выгружаются объекты парсинга.

СтрокаJSON - строка, которую парсим.

После отработки процедуры таблица будет заполнена объектами строки json.

По значениям колонок "ПозицияВстроке" и "Вес" можно получить значение объекта из строки JSON

сред(СтрокаJSON,СтрокаТаблицы.ПозицияВстроке,СтрокаТаблицы.Вес)

 или взять его же из колонки "Состав". Для объектов и массивов в "Состав" записывается строковое значение лежащее между скобками {} для объекта или [] для массива, со всеми внутренними вложениями.

 

 

Вступайте в нашу телеграмм-группу Инфостарт

JSON parser

См. также

Загрузка и выгрузка в Excel Универсальные функции Программист 1С:Предприятие 8 Россия Бесплатно (free)

Описанный ниже подход позволяет в три шага заполнять формулы в Excel файлы, вне зависимости от ОС сервера (MS Windows Server или Linux). Подход подразумевает отказ от работы с COM-объектом в пользу работы через "объектную модель документа" (DOM).

30.10.2025    3752    Abysswalker    9    

45

Универсальные функции Работа с интерфейсом Программист 1С:Предприятие 8 Бесплатно (free)

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

14.05.2025    7061    DeerCven    15    

60

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

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

21.05.2024    50755    dimanich70    83    

170

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Абонемент ($m)

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

1 стартмани

18.03.2024    7476    7    John_d    13    

59

Универсальные функции Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

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

12.02.2024    64120    atdonya    31    

70

Универсальные функции Программист 1С:Предприятие 8 Бесплатно (free)

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

30.11.2023    9347    ke.92@mail.ru    17    

68
Для отправки сообщения требуется регистрация/авторизация