Преобразование текста JSON в дерево значений. УФ (8.3)


Последнее время часто начал сталкиваться с форматом  JSON, и возникла необходимость быстро анализировать те или иные данные в этом формате, отбрасывая ненужные, но при больших объёмах данных зачастую было сложно разобраться в структуре. Так что это обработка для тех, кто хочет увидеть JSON в читабельном виде (знаю, похожие обработки есть на Инфостарте, но для моих данных они все вываливались с ошибками).
Обработка ни на что не претендует и сделана исключительно в целях сэкономить время для анализа JSON.

Обработка преобразовывает JSON в дерево значений. Работает на управляемых формах (8.3.11.2924).

Есть возможности:

  1. выбрать кодировку.
  2. считывать данные напрямую из файла. 
  3. считывать данные по ссылке (GET запрос).
  4. сразу на форме вставлять текст в формате JSON и преобразовывать его.

Из полезного по коду (по моему скромному мнению), вдруг кому пригодится:

Ниже представлен код рекурсивной функции, по преобразованию полученного массива данных JSON штатными средствами ("Новый ЧтениеJSON"), в дерево значений.

&НаСервере
Функция СформироватьДерево(НашаСтруктура,ТекущееДерево)

Для каждого СтрокаСтруктуры из НашаСтруктура цикл
Если ТипЗнч(СтрокаСтруктуры)=Тип("КлючИЗначение") тогда
ПодчиненнаяСтрока=ТекущееДерево.Строки.Добавить();
ПодчиненнаяСтрока.Ключ=СтрокаСтруктуры.Ключ;

Если ТипЗнч(СтрокаСтруктуры.Значение)=Тип("Соответствие") или ТипЗнч(СтрокаСтруктуры.Значение)=Тип("Массив")  тогда
СформироватьДерево(СтрокаСтруктуры.Значение,ПодчиненнаяСтрока)
Иначе
ПодчиненнаяСтрока.Значение=СтрокаСтруктуры.Значение;
КонецЕсли;
ИначеЕсли ТипЗнч(СтрокаСтруктуры)=Тип("Соответствие") или ТипЗнч(СтрокаСтруктуры)=Тип("Массив")  тогда
ПодчиненнаяСтрока=ТекущееДерево.Строки.Добавить();
ПодчиненнаяСтрока.Ключ="";
ПодчиненнаяСтрока.Значение="[...]";
СформироватьДерево(СтрокаСтруктуры,ПодчиненнаяСтрока);
Иначе
ПодчиненнаяСтрока=ТекущееДерево.Строки.Добавить();
ПодчиненнаяСтрока.Значение=СтрокаСтруктуры;
КонецЕсли;
КонецЦикла;

КонецФункции

 

Где "НашаСтруктура" — структуры/массивы JSON. А "ТекущееДерево" — строка созданного дерева значений.

Соответственно перед вызовом данной рекурсии необходимо создать переменную с типо Дерево значений и передать первую строку, в моём примере, что бы она не была пустая, заполняю её текстовым значение "Структура".

 

   Дерево= новый ДеревоЗначений;
Дерево.Колонки.Добавить("Ключ");
Дерево.Колонки.Добавить("Значение");
ВерхнийУровеньдерева=Дерево.Строки.Добавить();
ВерхнийУровеньдерева.Ключ="Структура JSON";
СформироватьДерево(НашиДанныеJSON,ВерхнийУровеньдерева);

 

Публикация первая, так что сильно не кричите.

5 Comments

  1. Fedor02

    Добрый день, вы написал «знаю, похожие обработки есть на Инфостарте, но для моих данных они все вываливались с ошибками» , чем ваша обработка отличается от существующих, и на сколько ваша обработка является универсальной и подходит для данных разной структуры?

    Reply
  2. burni4

    (2) что вы подразумеваете под данными разных структур? у JSON одна структура. По поводу обработок на инфостарте, похожую нашел вот эту

    https://infostart.ru/public/696196/

    и введя свои данные в формате JSON получил ошибку, о чем и отписался в данной теме, поэтому и решил написать свою.

    Reply
  3. uno-c

    Правильно ли понял, что Ваша обработка не осилит подобный json из-за ключей с пробелами и начинающихся с цифр? {«12979128»:{«сделка»:{1с_id»:12979128,»менеджер»:»v@»,»способ оплаты»:»prepayment»,»контрагент партнёра»: … » и тд. Не осилит, поскольку преобразует json в структуру для дальнейшей работы.

    Reply
  4. burni4

    (4) спасибо за замечание, исправил статью, перезалил обработку.

    Reply
  5. uno-c

    вот так с нумерацией элементов массива:

    &НаСервере
    Функция СформироватьПодстрокиДерева(ИтераторИзJson, ТекущаяСтрокаДерева, ИндексЭлементаМассива = 0)
    Для каждого Элемент из ИтераторИзJson цикл
    ДочерняяСтрокаДерева=ТекущаяСтрокаДерева.Строки.Добавить();
    //у типа итератора только два варианта: массив или соответствие
    Если ТипЗнч(ИтераторИзJson) = Тип(«Массив») Тогда
    ДочерняяСтрокаДерева.Ключ = «[» + ИндексЭлементаМассива + «]»;
    ИндексЭлементаМассива = ИндексЭлементаМассива + 1;
    Значение = Элемент;//элементы массива: примитивы, соответствия, массивы
    Иначе //итератор — соответствие, элементы — ключ и значение
    ДочерняяСтрокаДерева.Ключ = Элемент.Ключ;
    Значение = Элемент.Значение;//значения: примитивы, соответствия, массивы
    КонецЕсли;
    Если ТипЗнч(Значение)=Тип(«Соответствие») Тогда
    ДочерняяСтрокаДерева.Значение=»{» + Значение.Количество() +»}»;
    ДочерняяСтрокаДерева.Тип = «Запись»;
    СформироватьПодстрокиДерева(Значение, ДочерняяСтрокаДерева);
    ИначеЕсли ТипЗнч(Значение)=Тип(«Массив») Тогда
    ДочерняяСтрокаДерева.Значение=»[» + Значение.Количество() + «]»;
    ДочерняяСтрокаДерева.Тип = «Массив»;
    СформироватьПодстрокиДерева(Значение, ДочерняяСтрокаДерева);
    Иначе //примитив
    ДочерняяСтрокаДерева.Значение=Значение;
    ДочерняяСтрокаДерева.Тип = ТипЗнч(Значение);
    КонецЕсли;
    КонецЦикла;
    КонецФункции
    
    &НаСервере
    Процедура ЗаполнитьДеревоЖсон()
    ЧтениеЖсон = Новый ЧтениеJSON;
    ЧтениеЖсон.УстановитьСтроку(ОтветСервера);
    СоответствиеИзJson = ПрочитатьJSON(ЧтениеЖсон, Истина);
    
    Дерево= новый ДеревоЗначений;
    Дерево.Колонки.Добавить(«Ключ»);
    Дерево.Колонки.Добавить(«Значение»);
    Дерево.Колонки.Добавить(«Тип»);
    ВерхнийУровеньдерева=Дерево.Строки.Добавить();
    ВерхнийУровеньдерева.Ключ=»Дерево JSON»;
    СформироватьПодстрокиДерева(СоответствиеИзJson, ВерхнийУровеньдерева);
    ЗначениеВРеквизитФормы(Дерево,»ДеревоЖсон»);
    КонецПроцедуры

    Показать

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *