gifts2017

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

Опубликовал Anton S (ntemny) в раздел Программирование - Практика программирования

Простенький парсер 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,СтрокаТаблицы.ПозицияВстроке,СтрокаТаблицы.Вес)

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

 

 

См. также

Подписаться Добавить вознаграждение

Комментарии

1. BigB (BigB) 07.12.14 18:14
Тут парсер не тяжелый и не требует встраивания в конфигурацию.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа