Работа с форматом JSON стала стандартом для интеграции 1С с внешними веб-сервисами, мобильными приложениями и сторонними базами данных. Однако разработчики часто сталкиваются с трудностями при попытке прочитать не просто одиночный объект (структуру), а массив объектов JSON вида [{"ключ": "значение"}, {...}]. В этой статье мы подробно разберем, как правильно десериализовать такие массивы в 1С, как обходить их в цикле, а также рассмотрим важные технические нюансы, способные уберечь вас от ошибок пустого результата.
Когда мы получаем тело HTTP-ответа, оно представляет собой обычную строку. Попытка прочитать массив объектов стандартными методами иногда приводит к тому, что на выходе мы получаем пустую коллекцию или ошибку разбора. Проанализируем типичные причины этой проблемы:
izmer и resurs, а в цикле пытается обратиться к свойствам Kod или Imy. В результате 1С возвращает пустое значение или ошибку отсутствия свойства.Структура обязаны соответствовать правилам идентификаторов (не могут начинаться с цифры, содержать пробелы и спецсимволы). Если парсер пытается записать ключ "1_property" в структуру, происходит сбой.УстановитьСтроку() объекта ЧтениеJSON спотыкается на первом же символе, так как ожидает открывающую скобку [.Если вы уверены в качестве входящих данных и имена ключей в JSON гарантированно соответствуют правилам именования переменных в 1С, мы можем использовать стандартное чтение. Функция ПрочитатьJSON автоматически преобразует квадратные скобки JSON [...] в объект типа Массив, а фигурные скобки {...} — в Структура.
Рассмотрим пример кода для чтения такого массива:
// Предположим, что в переменной Джисон у нас хранится строка:
// [{"izmer": "ОС", "resurs": "Да"}, {"izmer": "Материал", "resurs": "Да"}]
ЧтениеДЖ = Новый ЧтениеJSON;
ЧтениеДЖ.УстановитьСтроку(Джисон);
// Второй параметр "Ложь" указывает, что объекты JSON нужно преобразовывать в Структуры 1С
МассивДжи = ПрочитатьJSON(ЧтениеДЖ, Ложь);
ЧтениеДЖ.Закрыть();
// Теперь мы можем обойти полученный массив в цикле
Для Каждого ТекущийЭлемент Из МассивДжи Цикл
// Обратите внимание: имена свойств чувствительны к регистру и должны точно совпадать с ключами JSON
ЗначениеИзмерения = ТекущийЭлемент.izmer;
ЗначениеРесурса = ТекущийЭлемент.resurs;
// Выполняем полезные действия с данными
Сообщить("Измерение: " + ЗначениеИзмерения + ", Ресурс: " + ЗначениеРесурса);
КонецЦикла;
Чтобы защитить код от падений при наличии нестандартных ключей в JSON, мы рекомендуем использовать второй параметр функции ПрочитатьJSON, установив его в значение Истина. В этом случае объекты внутри массива будут прочитаны не как Структура, а как Соответствие. Для Соответствия ключом может выступать абсолютно любая строка, включая пробелы и спецсимволы.
Разберем по шагам, как это реализовать:
ЧтениеДЖ = Новый ЧтениеJSON;
ЧтениеДЖ.УстановитьСтроку(Джисон);
// Указываем Истина во втором параметре для чтения в Соответствие
МассивДжи = ПрочитатьJSON(ЧтениеДЖ, Истина);
ЧтениеДЖ.Закрыть();
Для Каждого ТекущееСоответствие Из МассивДжи Цикл
// Доступ к значениям Соответствия осуществляется через метод Получить()
ЗначениеИзмерения = ТекущееСоответствие.Получить("izmer");
ЗначениеРесурса = ТекущееСоответствие.Получить("resurs");
Сообщить("Измерение: " + ЗначениеИзмерения + ", Ресурс: " + ЗначениеРесурса);
КонецЦикла;
Этот способ является наиболее отказоустойчивым при интеграции со сторонними веб-сервисами, формат данных которых вы не можете контролировать напрямую.
1. Очистка строки от BOM (невидимых символов)
Если веб-сервер возвращает строку с маркером последовательности байтов, парсер выдаст ошибку. Мы можем программно очистить строку перед чтением. Посмотрим на пример предобработки строки:
// Находим индекс начала реального JSON-массива
ИндексНачала = СтрНайти(Джисон, "[");
Если ИндексНачала > 1 Тогда
// Обрезаем все лишние невидимые символы до открывающей скобки
Джисон = Сред(Джисон, ИндексНачала);
КонецЕсли;
2. Потоковое чтение больших массивов данных
Если ваш JSON-массив содержит десятки тысяч элементов, стандартный метод ПрочитатьJSON загрузит их все в оперативную память одновременно, что может вызвать переполнение памяти или сильное замедление работы системы. В таких ситуациях мы применяем последовательное (потоковое) чтение токенов.
Проанализируем пример потокового обхода крупного массива:
ЧтениеДЖ = Новый ЧтениеJSON;
ЧтениеДЖ.УстановитьСтроку(Джисон);
// Читаем до тех пор, пока не встретим начало массива
Пока ЧтениеДЖ.Прочитать() Цикл
Если ЧтениеДЖ.ТипУзла = ТипУзлаJSON.НачалоМассива Тогда
Прервать;
КонецЕсли;
КонецЦикла;
// Начинаем перебор элементов внутри массива
Пока ЧтениеДЖ.Прочитать() Цикл
// Если встретили конец массива, прекращаем чтение
Если ЧтениеДЖ.ТипУзла = ТипУзлаJSON.КонецМассива Тогда
Прервать;
КонецЕсли;
// Если встретили начало объекта, считываем только его в структуру
Если ЧтениеДЖ.ТипУзла = ТипУзлаJSON.НачалоОбъекта Тогда
// Считываем один объект, и указатель автоматически сдвигается дальше
ТекущийЭлемент = ПрочитатьJSON(ЧтениеДЖ, Ложь);
// Сразу обрабатываем данные, не накапливая их в памяти
ОбработатьДанныеЭлемента(ТекущийЭлемент);
КонецЕсли;
КонецЦикла;
ЧтениеДЖ.Закрыть();
Используя данный подход, вы сможете обрабатывать файлы практически любого объема с минимальным и стабильным потреблением ресурсов сервера.
3. Проблема строгого соответствия стандарту (Strict Mode)
Обратите внимание, что парсер 1С очень чувствителен к валидности JSON. Например, лишняя запятая перед закрывающей скобкой вида [{"а": 1},] приведет к ошибке чтения, хотя современные веб-браузеры легко игнорируют подобные недочеты. Всегда проверяйте валидность входящего потока перед обработкой в 1С.