Парсер JSON (Штатные средства 1С 8.3.6)

29.09.16

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

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

Трудности

Однажды пришлось столкнуться с обработкой больших пакетов данных, и обработка пакета 2.2 мб за ~ 60 секунд, для нас это было долго.

Решили опробовать штаного зверя, обход такого пакета данных по средствам чтения занял ~ 1-1.5 сек.

Пока ЧтениеJSON.Прочитать() Цикл

Но из-за того, что куча сервисов  уже работает со структурой данных, который возвращает парсер от  Переверзева Александра, было принято решение сделать аналогичную структуру только штатными средствами платформы

Результат

В итоге обработка такого пакета данных в 2.2 мб с возвратом уже привычной структуры заняла ~ 2.5 секунды.

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

Пример части  кода 1С:JSON и штаного парсера ниже.

// JSON парсер.
&НаКлиенте
Функция ПрочитатьJSONИзФайла(Значение, Стандарт = Истина, ПредставленияСсылок = Ложь) Экспорт 
    
    Попытка
        ЧтениеJSON = Новый ЧтениеJSON;
        ЧтениеJSON.Закрыть();
        
        Возврат jsonПрочитатьПлатформой(Значение);
    Исключение
        Возврат jsonПрочитатьИнициализация(Значение, Стандарт, ПредставленияСсылок);
    КонецПопытки;
    
КонецФункции // ПрочитатьJSON()

&НаКлиенте
Функция jsonПрочитатьПлатформой(Значение)

    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(Значение);
    
    Результат = Неопределено;
    СформироватьДерево(ЧтениеJSON, Результат);
    
    ЧтениеJSON.Закрыть();
    
    Возврат Результат;

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

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

Надеюсь, пример функции будет полезен и сэкономит кому-то время.

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

Парсер JSON 1С JSON штанный парсер 1с JSON 1С штанный парсер JSON в 1с

См. также

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

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

14.05.2025    5426    DeerCven    15    

57

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

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

21.05.2024    46370    dimanich70    83    

164

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

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

1 стартмани

18.03.2024    6855    6    John_d    13    

59

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

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

12.02.2024    57440    atdonya    31    

68

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

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

30.11.2023    8627    ke.92@mail.ru    17    

68

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

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

28.08.2023    22793    YA_418728146    8    

174
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Fragster 1163 29.09.16 18:20 Сейчас в теме
Глобальный контекст.ПрочитатьJSON (Global context.ReadJSON)
Глобальный контекст (Global context)
ПрочитатьJSON (ReadJSON)
Синтаксис:

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

<ЧтениеJSON> (обязательный)

Тип: ЧтениеJSON.
Объект чтения JSON.
<ПрочитатьВСоответствие> (необязательный)

Тип: Булево.
Если установлено Истина, чтение объекта JSON будет выполнено в Соответствие.
Если установлено Ложь, объекты будут считываться в объект типа Структура.
Примечание. При десериализации объектов JSON в структуру необходимо помнить о требованиях к ключам структуры. Если при десериализации объекта будет найдено имя свойства, недопустимое для ключа структуры, то будет вызвано исключение.
Значение по умолчанию: Ложь.
<ИменаСвойствСоЗначениямиДата> (необязательный)

Тип: Массив, Строка, ФиксированныйМассив.
Массив, элементы которого содержат имена свойств JSON. Для указанных свойств будет вызвано восстановление даты из строки согласно формату, указанному в параметре ОжидаемыйФорматДаты.
Если имя свойства указано в этом параметре и в параметре ИменаСвойствДляОбработкиВосстановления, то для таких свойств восстановление осуществляется в функции восстановления.
Если восстановление даты из значения свойства невозможно, то будет сгенерировано исключение.
Значение по умолчанию: Неопределено.
<ОжидаемыйФорматДаты> (необязательный)

Тип: ФорматДатыJSON.
Ожидаемый формат даты при десериализации объекта в формате JSON.
Если десериализуемое значение не является строкой и имеет формат даты, отличный от ожидаемого, то будет вызвано исключение.
Значение по умолчанию: ISO.
<ИмяФункцииВосстановления> (необязательный)

Тип: Строка.
Данная функция вызывается при чтении каждого свойства и должна иметь следующие параметры:
<Свойство> - значение типа Строка, указывается только при чтении объектов JSON,
<Значение> - значение допустимого для сериализации типа,
<ДополнительныеПараметры>.
Возвращаемое значение - произвольного типа.
Если данный параметр задан и не задан параметр МодульФункцииВосстановления, и наоборот, будет вызвано исключение.
Если функция не установлена, то при вызове метода ПрочитатьJSON, параметр ИменаСвойствСоЗначениямиДата игнорируется.
Значение по умолчанию: Неопределено.
<МодульФункцииВосстановления> (необязательный)

Тип: УправляемаяФорма; КомандаКомандногоИнтерфейса; ОбщийМодуль.
Указывает модуль, процедура которого будет использована для восстановления значения. В зависимости от типа параметра будет вызван соответствующий метод:
УправляемаяФорма - будет вызван метод модуля указанной управляемой формы.
КомандаКомандногоИнтерфейса - будет вызван метод модуля команды командного интерфейса.
ОбщийМодуль - будет вызван метод неглобального общего модуля.

Значение по умолчанию: Неопределено.
<ДополнительныеПараметрыФункцииВосстановления> (необязательный)

Тип: Произвольный.
Дополнительные параметры, которые будут переданы в функцию восстановления значений.
Значение по умолчанию: Неопределено.
<ИменаСвойствДляОбработкиВосстановления> (необязательный)

Тип: Массив.
Массив имен свойств JSON, для которых будет вызвана функция восстановления.
Параметр игнорируется, если не установлен параметр ИмяФункцииВосстановления.
Значение по умолчанию: Неопределено.
<МаксимальнаяВложенность> (необязательный)

Тип: Число.
Максимальный уровень вложенности объекта JSON.
При превышении уровня вложенности будет сгенерировано исключение.
Значение по умолчанию: 500.
Возвращаемое значение:

Тип: Произвольный.

Описание:

Считывает значение из JSON-текста или файла. JSON-текст должен быть корректным.

Доступность:

Тонкий клиент, сервер, толстый клиент, внешнее соединение.
Примечание:

Массив будет десеарилизован в массив. Объект JSON будет преобразован в соответствие или структуру (если ключ структуры окажется недопустимым, будет вызвано исключение).
Для дат действует аналогично методу ПрочитатьДатуJSON.
Во время выполнения метода может быть вызвана пользовательская функция для восстановления значения - для этого следует использовать параметр ИмяФункцииВосстановления. Функция восстановления должна быть описана с директивой &НаСервере или &НаКлиенте. Использование функции вне контекста не допускается.
--------------------------------------------------------------------------------

Методическая информация
SagittariusA; cezarj; Irwin; AskezaMax; denis_aka_wolf; YoungHero; kuzyara; echo77; dark_wolf; dour-dead; vano-ekt; +11 Ответить
2. ltfriend 30.09.16 06:37 Сейчас в теме
3. Fragster 1163 30.09.16 11:51 Сейчас в теме
(2) ltfriend, это цитата из синтакс-помощника про встроенный в платформу метод, который делает то же самое, что и код из статьи.
4. Inkasor 28 30.09.16 12:51 Сейчас в теме
(3) Fragster, там не всё так просто с этим методом, он существует, но не очень быстро работает :) я как раз на INFOSTART EVENT DEVELOPER 2016 хочу уделить этому некоторое время в докладе :) Впрочем, мы измеряем скорость по другому, не в потоке мб/с, а в количестве объектов обмена в секунду.
5. Fragster 1163 30.09.16 13:14 Сейчас в теме
(4) Inkasor, есть подозрение, что указанный в статье способ еще более медленный, чем платформенный. причем платформенный позволяет еще и некоторые преобразования данных провернуть. Например у меня так структуры вида XMLТип + гуид преобразуются в ссылки на объекты метаданных.
6. Inkasor 28 30.09.16 13:30 Сейчас в теме
(5) Fragster, "было принято решение сделать аналогичную структуру", legacy же :) мы у себя по другому разбираем. Там ещё очень важный момент с тем, какими объектами мы друг с другом обмениваемся. Если делать обмен 1С-1С, ПрочитатьJSON() возможно будет самым лучшим решением, но если 1С-что-то другое, тогда ЧтениеJSON.ТекущееЗначение возможно, будет быстрей, тут всё зависит от структуры объекта обмена. Про ЗаписатьJSON вообще молчу :)
7. ltfriend 30.09.16 23:55 Сейчас в теме
(3) т.е. статю вы не читали?
8. dour-dead 271 01.10.16 12:10 Сейчас в теме
(1) Fragster, Спасибо (будем юзать штатный метод)! Как то не внимательно значит я читал новые возможности для работы с JSON.
Сделал замеры по времени на разных видах данных, частично метод проигрывает от 2 до 5 раз) .

Прикрепленные файлы:
9. Fragster 1163 01.10.16 22:12 Сейчас в теме
(8) ну, судя по замерам - во всех случаях от 5 до 10 раз. просто надо выводить одинаковое количество знаков после запятой, чтобы в глаза бросилось.
14. echo77 1935 22.07.17 17:18 Сейчас в теме
(8) В итоге, Метод глобального контекста ПрочитатьJSON() быстрее этой публикации получается?
15. dour-dead 271 15.09.17 13:56 Сейчас в теме
(14) Да, но метод подходит для специфичного хранения данных (хотя по факту я такое не встречал)
(10)
Спасибо за функцию, она не чувствительна к именам свойств в отличии от типовой, в которой - "Если при десериализации объекта будет найдено имя свойства, недопустимое для ключа структуры, то будет вызвано исключение."
10. prog77 05.10.16 10:16 Сейчас в теме
Спасибо за функцию, она не чувствительна к именам свойств в отличии от типовой, в которой - "Если при десериализации объекта будет найдено имя свойства, недопустимое для ключа структуры, то будет вызвано исключение."
11. Fragster 1163 05.10.16 11:23 Сейчас в теме
(10) prog77, вы плохо прочитали синтакс-помощник.
13. VasilVtoroy 08.10.16 00:28 Сейчас в теме
(10) prog77, есть параметр, который позволяет читать в Соответствие и тогда проблемы нет
nikolav; echo77; +2 Ответить
16. prog77 17.09.17 12:12 Сейчас в теме
(13)
Да, так и делаю теперь...
12. rus128 2 05.10.16 12:58 Сейчас в теме
Заметил опечатку:
"Пример части кода 1С:JSON и шта(Т)ного парсера ниже."
17. jo0506 20 20.03.18 06:16 Сейчас в теме
"jsonПрочитатьИнициализация" - Это что, нигде нет ссылки на эту функцию???
18. dour-dead 271 20.03.18 15:26 Сейчас в теме
(17) jsonПрочитатьИнициализация это из обработки https://infostart.ru/public/119601/
jobkostya1c_ERP; Saer; +2 Ответить
19. jobkostya1c_ERP 101 27.03.19 16:35 Сейчас в теме
Проверил Ваш парсер для простых случаев с глубиной заранее описанного формата с глубиной не более 2-х.
Прикрепленные файлы:
ЧтениеJSON.epf
тестовый файл json-ответа.txt
20. jobkostya1c_ERP 101 27.03.19 16:38 Сейчас в теме
Нужно было убедиться что корректно в соответствием и массив читает для всех случаев.
21. user886140 30.07.19 09:19 Сейчас в теме
22. unknow_user 18.04.20 09:59 Сейчас в теме
Спасибо автору! Ещё тут наглядно продемонстрирована работа с Чтением/Записью JSON:
https://1c-freelancer.ru/programmistu/1s8-x/metadannye/rabota-s-json-v-1s
23. pashamix 11.05.20 15:43 Сейчас в теме
Спасибо, пригодилось. В то время, как штатный вариант выдал ошибку.
24. Manticor 66 04.06.20 15:47 Сейчас в теме
Добрый день. Как переделать приведенную вами функцию, чтобы она возвращала структуру, не соответствие.
25. dour-dead 271 04.06.20 16:19 Сейчас в теме
(24) добрый, проще использовать "ПрочитатьJSON", где есть параметр "ПрочитатьВСоответствие"

ПрочитатьJSON(<ЧтениеJSON>, <ПрочитатьВСоответствие>>)
Параметры:
<ЧтениеJSON> (обязательный)
Тип: ЧтениеJSON.
Объект чтения JSON.
<ПрочитатьВСоответствие> (необязательный)
Тип: Булево.
Если установлено Истина, чтение объекта JSON будет выполнено в Соответствие.
Если установлено Ложь, объекты будут считываться в объект типа Структура.
26. Manticor 66 04.06.20 18:16 Сейчас в теме
(25)
ПрочитатьВСоответствие

я пробовал так делать, этот метод хорош, когда нет массивов, а ежели у меня сам текст json на 80 листах word и со сложными структурами и массивами в которых есть структуры - то с использваонием ПрочитатьВСоответствие выдает ошибку.
27. Yan83 18.07.20 11:13 Сейчас в теме
...обработка пакета 2.2 мб за ~ 60 секунд, для нас это было долго.


Тут явно дело не в начальном преобразовании файла в дерево/структуру, а в дальнейшей обработке, которая скорее всего в цикле. А так ПрочитатьJSON() очень шустрая штука, 68000 позиций в файле 48 Мб у меня проскакивали за 6 секунд и это на виртуальной машине, что крутится на ноутбуке 2011 года (i7 второе поколение, 6 Гб ОЗУ из 16 отдано ВМ). А вот обход и обработка после затягивается на десятки минут. Было бы интересно посмотреть именно идеи оптимизации последующей обработки полученной структуры с замерами. Буду благодарен за примеры статей.
28. VeleX 26.08.20 13:26 Сейчас в теме
Большое спасибо за публикацию! Очень помогла!
Пришлось парсить JSON файл, который ронял платформу при использовании стандартного ПрочитатьJSON(). Ваш метод просто спас!
29. PerlAmutor 160 10.09.20 19:17 Сейчас в теме
До сих пор не укладывается в голове, что JSON созданный для Веб технологий невозможно распарсить на Web клиенте 1С без вызова сервера.
30. ivela86 21.11.21 23:01 Сейчас в теме
Спасибо огромное . Вы гений.
31. Никулин Леонид 4 28.05.24 15:31 Сейчас в теме
В БСП:
УправлениеКонтактнойИнформациейСлужебный.СтрокуJSONВСтруктуру(Значение)
УправлениеКонтактнойИнформациейСлужебный.СтруктураВСтрокуJSON(Значение)
32. Никулин Леонид 4 28.05.24 16:21 Сейчас в теме
И еще:
ОбщегоНазначенияДокументооборот.ЗначениеИзСтрокиJSON(СтрокаJSON)
ОбщегоНазначенияДокументооборот.ЗначениеВСтрокуJSON(Значение)
Для отправки сообщения требуется регистрация/авторизация