Парсер 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.3.24)

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

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

1 стартмани

18.03.2024    2670    0    John_d    8    

54

GUID в 1С 8.3 - как с ними быть

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

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

12.02.2024    4606    atdonya    22    

45

Переоткрытие внешних обработок

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

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

30.11.2023    3960    ke.92@mail.ru    16    

61

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

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

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

28.08.2023    8818    YA_418728146    6    

141

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

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

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

2 стартмани

22.08.2023    2071    21    progmaster    7    

3

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

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

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

1 стартмани

13.10.2022    16143    133    sapervodichka    112    

129

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

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

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

18.07.2022    7243    quazare    8    

109
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Fragster 1138 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 954 30.09.16 06:37 Сейчас в теме
3. Fragster 1138 30.09.16 11:51 Сейчас в теме
(2) ltfriend, это цитата из синтакс-помощника про встроенный в платформу метод, который делает то же самое, что и код из статьи.
4. Inkasor 28 30.09.16 12:51 Сейчас в теме
(3) Fragster, там не всё так просто с этим методом, он существует, но не очень быстро работает :) я как раз на INFOSTART EVENT DEVELOPER 2016 хочу уделить этому некоторое время в докладе :) Впрочем, мы измеряем скорость по другому, не в потоке мб/с, а в количестве объектов обмена в секунду.
5. Fragster 1138 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 954 30.09.16 23:55 Сейчас в теме
(3) т.е. статю вы не читали?
8. dour-dead 271 01.10.16 12:10 Сейчас в теме
(1) Fragster, Спасибо (будем юзать штатный метод)! Как то не внимательно значит я читал новые возможности для работы с JSON.
Сделал замеры по времени на разных видах данных, частично метод проигрывает от 2 до 5 раз) .

Прикрепленные файлы:
9. Fragster 1138 01.10.16 22:12 Сейчас в теме
(8) ну, судя по замерам - во всех случаях от 5 до 10 раз. просто надо выводить одинаковое количество знаков после запятой, чтобы в глаза бросилось.
14. echo77 1868 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 1138 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 19 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 100 27.03.19 16:35 Сейчас в теме
Проверил Ваш парсер для простых случаев с глубиной заранее описанного формата с глубиной не более 2-х.
Прикрепленные файлы:
ЧтениеJSON.epf
тестовый файл json-ответа.txt
20. jobkostya1c_ERP 100 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 129 10.09.20 19:17 Сейчас в теме
До сих пор не укладывается в голове, что JSON созданный для Веб технологий невозможно распарсить на Web клиенте 1С без вызова сервера.
30. ivela86 21.11.21 23:01 Сейчас в теме
Спасибо огромное . Вы гений.
Оставьте свое сообщение