Как правильно экранировать JSON в строке 1С

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

При работе с JSON в среде 1С:Предприятие программисты часто сталкиваются с трудностями при попытке вставить готовый JSON-код непосредственно в текст модуля. Основная проблема заключается в том, что стандарт JSON активно использует двойные кавычки и фигурные скобки, которые в 1С имеют специальное назначение. Если просто скопировать JSON-структуру в переменную, конфигуратор выдаст ошибку синтаксиса, например, «Ожидается ключевое слово 'КонецПроцедуры'», так как парсер 1С воспримет первую же кавычку внутри JSON как завершение строки кода.

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

Причина возникновения ошибок синтаксиса

Давайте проанализируем ситуацию: когда вы пишете СтрокаJSON = "{"widget": "on"}";, платформа интерпретирует это следующим образом: открывается строковый литерал символом ", затем идет текст до следующей кавычки перед словом widget. В этот момент 1С считает, что строка закончилась. Все последующие символы (текст JSON) воспринимаются как ошибочный код вне контекста строки, что и приводит к аварийному завершению компиляции модуля.

Решение 1: Правильное оформление многострочных литералов

Если нам необходимо жестко прописать JSON внутри кода, мы должны соблюдать два правила синтаксиса 1С:

  1. Символ вертикальной черты: Каждая новая строка внутри одного строкового литерала должна начинаться с символа |.
  2. Удвоение кавычек: Чтобы внутри строки 1С отобразилась одна двойная кавычка, в коде конфигуратора их нужно написать две подряд ("").

Рассмотрим пример правильного написания JSON-структуры в коде:


Процедура Кнопка1Нажатие(Элемент)
    СтрокаJSON = 
    "{
    |""widget"": {
    |    ""debug"": ""on"",
    |    ""window"": {
    |        ""title"": ""Sample Widget"",
    |        ""width"": 500
    |    }
    |}
    |}";
    
    // Теперь строку можно прочитать
    Чтение = Новый ЧтениеJSON;
    Чтение.УстановитьСтроку(СтрокаJSON);
    Данные = ПрочитатьJSON(Чтение);
    Чтение.Закрыть();
КонецПроцедуры

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

Решение 2: Программное экранирование спецсимволов

Иногда JSON формируется динамически из строковых переменных. В этом случае нам нужно самостоятельно «маскировать» символы, которые могут нарушить структуру JSON (переносы строк, табуляции, обратные слеши). Проанализируем вспомогательную функцию, которая поможет подготовить обычный текст для вставки в значение JSON-поля:


Функция MyJSONМаскировать(Знач Стр)
    // Важно: сначала заменяем обратный слеш, чтобы не испортить последующие замены
    Стр = СтрЗаменить(Стр, "\", "\\");
    Стр = СтрЗаменить(Стр, Символы.ПС, "\n");
    Стр = СтрЗаменить(Стр, Символы.ВК, "\r");
    Стр = СтрЗаменить(Стр, Символы.Таб, "\t");
    Стр = СтрЗаменить(Стр, "/", "\/");
    Стр = СтрЗаменить(Стр, """", "\""");
    Возврат Стр;
КонецФункции

Эта функция реализует базовые требования стандарта RFC 7159. Выясним причину важности порядка замен: если вы сначала замените символ переноса строки на \n, а потом начнете заменять одиночный слеш на двойной, то ваш \n превратится в \\n, что будет воспринято парсером как обычный текст, а не управляющий символ.

Решение 3: Использование встроенных объектов ЗаписьJSON (Платформа 8.3.6+)

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

Рассмотрим по шагам процесс создания валидного JSON:


// 1. Подготовим данные в виде Структуры или Массива
ДанныеДляЗаписи = Новый Структура;
ДанныеДляЗаписи.Вставить("Название", "Пример ""Экранирования""");
ДанныеДляЗаписи.Вставить("Путь", "C:\Windows\System32");

// 2. Настроим запись
Запись = Новый ЗаписьJSON;
ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Авто, " ");
Запись.УстановитьСтроку(ПараметрыЗаписи);

// 3. Сериализуем данные
ЗаписатьJSON(Запись, ДанныеДляЗаписи);

// 4. Получим результат
РезультатJSON = Запись.Закрыть();
// Результат будет: {"Название": "Пример \"Экранирования\"", "Путь": "C:\\Windows\\System32"}

Использование метода ЗаписатьJSON() гарантирует, что все вложенные кавычки будут экранированы символом \, а пути к файлам получат правильные двойные слеши. Это исключает ошибки при передаче данных через веб-сервисы или HTTP-запросы.

Работа с файлами и внешними источниками

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


ИмяФайла = "C:\temp\data.json";
ТекстДок = Новый ТекстовыйДокумент;
ТекстДок.Прочитать(ИмяФайла, КодировкаТекста.UTF8);
СтрокаJSON = ТекстДок.ПолучитьТекст();

// Теперь разбираем строку в объект 1С
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);
СтруктураДанных = ПрочитатьJSON(Чтение);
Чтение.Закрыть();

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

Особенности обмена между версиями 8.1 и 8.3

Стоит учитывать, что в старых версиях платформы (8.1, 8.2 до определенных релизов) нативной поддержки JSON нет. Если вам нужно передать JSON из современной базы 8.3 в старую систему на 8.1, рекомендуется использовать максимально простой формат данных:

Для передачи данных из 8.3 в 8.1 через POST-запрос, используйте следующий шаблон:


Запрос = Новый HTTPЗапрос("/api/data");
Запрос.Заголовки.Вставить("Content-Type", "application/json");
// Важно явно указать кодировку без BOM
Запрос.УстановитьТелоИзСтроки(РезультатJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

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

← На главную