Как десериализовать JSON с двоеточиями и спецсимволами в ключах в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С с внешними REST API или веб-сервисами разработчики регулярно сталкиваются с необходимостью разбора (десериализации) входящих строк в формате JSON. Платформа 1С предоставляет для этого удобные встроенные инструменты. Однако стандартные механизмы могут преподнести неприятные сюрпризы, если структура JSON-файла содержит специфические ключи — например, имена свойств с двоеточиями, точками, дефисами или начинающиеся с цифр. В этой статье мы подробно разберем, почему возникает популярная ошибка десериализации, как правильно настроить чтение таких данных и как корректно извлечь значения, даже если ключи заранее неизвестны.

Выясняем причину: почему падает чтение в Структуру

Рассмотрим типичную ситуацию. Нам поступает JSON-строка, в которой одно или несколько свойств имеют имена вида 0:1, @type или user-id. При попытке прочитать эту строку стандартным методом платформа выдает ошибку:

«Недопустимое имя свойства для чтения JSON в объект Структура»

Давайте проанализируем, почему это происходит. По умолчанию метод ПрочитатьJSON() преобразует все объекты JSON во встроенный тип данных 1С — Структура. Ключи структуры в платформе 1С обязаны строго соответствовать правилам именования переменных во встроенном языке. Это значит, что имя свойства структуры:

  1. Не может начинаться с цифры.
  2. Не может содержать спецсимволы, такие как двоеточие (:), дефис (-), точка (.), собачка (@) и пробелы.
  3. Должно состоять только из букв, цифр и символов подчеркивания.

Поскольку имя свойства 0:1 содержит двоеточие и начинается с цифры, платформа физически не может создать свойство структуры с таким именем. В результате выполнение кода аварийно завершается.

Решение по шагам: используем Соответствие вместо Структуры

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

Разберем, как реализовать этот подход на практике. Для этого в метод ПрочитатьJSON() нужно передать второй параметр — ИспользоватьСоответствие, установив его в значение Истина. Посмотрим на пример кода:


// Создаем объект для чтения JSON
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);

// Читаем данные, явно указав использование Соответствия
РезультатДесериализации = ПрочитатьJSON(ЧтениеJSON, Истина);

ЧтениеJSON.Закрыть();

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

Разбираем ловушку: почему Получить("images")[0] возвращает Неопределено

После успешной десериализации разработчики часто сталкиваются со следующей проблемой при попытке обратиться к вложенным данным. Например, конструкция СтруктураОтвета.Получить("images")[0] неожиданно возвращает Неопределено, хотя в отладчике наглядно видно, что коллекция заполнена. Выясним, почему так происходит.

Здесь кроются две важные технические особенности работы с коллекциями в 1С:

1. Строковые ключи вместо числовых индексов

В формате JSON ключи объектов всегда являются строковыми значениями, даже если они выглядят как числа. Если исходный JSON содержал структуру картинок в виде объекта с числовыми именами свойств, например: "images": {"0": "link1", "1": "link2"}, то после десериализации ключами во вложенном соответствии станут строковые значения "0" и "1", а не числа 0 и 1.

Платформа 1С строго различает типы ключей в соответствии. Обращение к элементу по числу 0 вернет Неопределено, потому что ключ "0" (строка) не равен числу 0. Чтобы исправить это, мы должны передавать строковый ключ:


Картинки = СтруктураОтвета.Получить("images");
Если Картинки <> Неопределено Тогда
    ПерваяКартинка = Картинки.Получить("0"); // Передаем строковый ключ "0"
КонецЕсли;

2. Объект JSON вместо Массива JSON

Если в исходном тексте JSON данные были заключены в фигурные скобки {} (объект), а не в квадратные [] (массив), то платформа прочитает их как Соответствие. У типа данных Соответствие в 1С нет понятия обращения по порядковому индексу. К нему невозможно обратиться так, как к обычному массиву. Если ключи генерируются динамически на стороне внешнего API и заранее нам неизвестны, мы не сможем прочитать их по фиксированному ключу.

Обход соответствия с динамическими и неизвестными ключами

Если API возвращает произвольные ключи (например, идентификаторы объектов или даты), единственным надежным способом получить данные является перебор коллекции в цикле. Давайте посмотрим, как правильно организовать обход полученного соответствия:


Изображения = СтруктураОтвета.Получить("images");

Если ТипЗнч(Изображения) = Тип("Соответствие") Тогда
    // Обходим коллекцию в цикле "Для Каждого"
    Для Каждого Элемент Из Изображения Цикл
        ИмяКлюча = Элемент.Ключ;            // Здесь будет наш сложный ключ, например "0:1"
        ЗначениеКартинки = Элемент.Значение; // Сами данные
        
        // Выполняем обработку полученных данных
        Сообщить("Ключ: " + ИмяКлюча + ", Значение: " + ЗначениеКартинки);
    КонецЦикла;
КонецЕсли;

Используя цикл Для Каждого, мы последовательно получаем доступ ко всем элементам соответствия, независимо от того, насколько сложные спецсимволы присутствуют в их ключах.

Альтернативные методы решения проблемы

В некоторых случаях разработчикам критически важно работать именно с типом Структура — например, если вся остальная логика конфигурации завязана на обращение к свойствам через точку (Ответ.images.ИмяСвойства) или если десериализованный объект необходимо передавать в типовые процедуры, жестко ожидающие только структуры. Рассмотрим два альтернативных подхода.

Подход А: Предварительная замена недопустимых символов в строке JSON

Мы можем обработать исходную JSON-строку перед ее передачей в объект ЧтениеJSON, чтобы заменить все недопустимые спецсимволы в именах свойств на разрешенные (например, на знак подчеркивания _).

Если проблемные ключи нам известны заранее, мы можем использовать простую замену:


// Заменяем двоеточие в конкретном ключе
СтрокаJSON = СтрЗаменить(СтрокаJSON, """0:1""", """Prop_0_1""");

Если же ключи динамические, можно прибегнуть к регулярным выражениям через COM-объект VBScript.RegExp (для Windows-серверов). Это позволит найти все двоеточия или дефисы, расположенные именно в именах свойств (внутри кавычек слева от разделительного двоеточия JSON), и заменить их на безопасные символы. Важно настраивать регулярное выражение аккуратно, чтобы случайно не повредить двоеточия внутри значений (например, в ссылках или датах).

Подход Б: Низкоуровневое потоковое чтение JSON

Если файл JSON имеет огромный размер или его структура крайне сложна, чтение всей строки в память может быть нерациональным. В такой ситуации мы можем использовать объект ЧтениеJSON для последовательного перебора элементов «на лету».

Этот метод позволяет перехватывать имена свойств в процессе разбора и подменять их программно перед заполнением результирующей структуры. Проанализируем пример такой реализации:


ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);

РезультирующаяСтруктура = Новый Структура;

Пока ЧтениеJSON.Прочитать() Цикл
    Если ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.ИмяСвойства Тогда
        ИмяСвойства = ЧтениеJSON.ТекущееЗначение;
        
        // Если имя свойства содержит недопустимый символ, трансформируем его
        Если ИмяСвойства = "0:1" Тогда
            ИмяСвойства = "Prop_0_1";
        КонецЕсли;
        
        // Читаем следующее значение, соответствующее этому свойству
        ЧтениеJSON.Прочитать();
        ЗначениеСвойства = ЧтениеJSON.ТекущееЗначение;
        
        // Записываем в структуру уже под очищенным именем
        РезультирующаяСтруктура.Вставить(ИмяСвойства, ЗначениеСвойства);
    КонецЕсли;
КонецЦикла;

ЧтениеJSON.Закрыть();

Таким образом, мы детально разобрали особенности десериализации нестандартных JSON-строк в 1С. Использование параметра ИспользоватьСоответствие в методе ПрочитатьJSON() является наиболее быстрым, простым и надежным решением проблемы недопустимых символов в именах свойств. А понимание различий между типами ключей и коллекциями поможет вам легко извлекать нужные данные в любых сценариях интеграции.

← На главную