Как избежать ошибки "Недопустимое имя свойства" при чтении JSON в 1С?

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

При работе с внешними системами и обменом данными в формате JSON разработчики 1С часто сталкиваются с ситуацией, когда стандартный механизм чтения JSON в объект Структура платформы выдает ошибку "Недопустимое имя свойства". Эта проблема возникает, когда имена свойств (ключи) в JSON-объекте не соответствуют строгим правилам именования переменных во встроенном языке 1С. В этой статье мы подробно разберем причину возникновения такой ошибки и рассмотрим, как ее корректно обрабатывать, используя объект Соответствие.

Анализируем проблему: почему 1С не может прочитать JSON с числовыми ключами?

Давайте рассмотрим типичную ситуацию, описанную в нашей теме. Мы получаем JSON-ответ, содержащий объект с числовыми строковыми ключами, например, такой:


{
  "distribution": {
    "0": 35,
    "200": 30,
    "400": 18,
    "600": 8,
    "800": 5
  }
}

При попытке прочитать этот JSON с помощью стандартного вызова:


ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.ОткрытьФайл(ПутьКФайлу); // или ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
Ответ = ПрочитатьJSON(ЧтениеJSON);

мы получаем ошибку: "Недопустимое имя свойства: '800' для чтения JSON в объект Структура". Почему это происходит?

1. Стандарт JSON и имена свойств

Для начала, важно понимать, что представленный выше JSON полностью соответствует стандарту JSON (RFC 7159). Согласно этому стандарту, имена свойств (ключи) в JSON-объектах должны быть строками и заключаться в двойные кавычки. Числовые строки, такие как "0", "200", "800", являются абсолютно корректными строковыми ключами в JSON. Стандарт не накладывает ограничений на то, что первый символ строки должен быть буквой или что она не может состоять только из цифр.

2. Особенности объекта "Структура" в 1С

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

Когда 1С сталкивается с ключом, таким как "800" (который начинается с цифры) или "#value" (который содержит специальный символ '#'), при попытке создать для него свойство в объекте Структура, она не может это сделать, поскольку это нарушает правила именования. Именно поэтому возникает ошибка "Недопустимое имя свойства". Платформа 1С обрабатывает JSON последовательно или с конца, и как только она натыкается на первое же недопустимое имя свойства, она выдает ошибку.

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

Самым правильным и рекомендуемым решением данной проблемы является использование объекта Соответствие 1С для хранения данных JSON. Соответствие, в отличие от Структуры, предназначено для хранения пар "ключ-значение", где ключи могут быть произвольными строками (или даже другими типами), и не имеют ограничений на их формат, подобно именам переменных. Это делает Соответствие идеальным инструментом для работы с JSON-объектами, чьи ключи не соответствуют строгим правилам именования Структуры в 1С.

1. Чтение JSON в Соответствие

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


ЧтениеJSON = Новый ЧтениеJSON;
// Пример чтения из строки
СтрокаJSON = "{""distribution"":{ ""0"":35, ""200"":30, ""400"":18, ""600"":8, ""800"":5 }}";
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);

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

// Проверяем тип полученного объекта
Если ТипЗнч(Ответ) = Тип("Соответствие") Тогда
    Сообщить("JSON успешно прочитан в Соответствие.");
Иначе
    Сообщить("Что-то пошло не так. Получен объект типа: " + ТипЗнч(Ответ));
КонецЕсли;

2. Доступ к данным в Соответствии

После того как JSON прочитан в Соответствие, доступ к его элементам осуществляется не через точку (как у Структуры), а через квадратные скобки с указанием ключа в виде строки. Рассмотрим на примере нашего JSON:


// Доступ к верхнему уровню "distribution"
СоответствиеDistribution = Ответ["distribution"];

// Проверяем, что это тоже Соответствие
Если ТипЗнч(СоответствиеDistribution) = Тип("Соответствие") Тогда
    Сообщить("Объект 'distribution' также является Соответствием.");
Иначе
    Сообщить("Ошибка: 'distribution' не является Соответствием.");
КонецЕсли;

// Доступ к значениям по числовым строковым ключам
Значение0 = СоответствиеDistribution["0"];
Значение200 = СоответствиеDistribution["200"];
Значение800 = СоответствиеDistribution["800"];

Сообщить("Значение для ключа '0': " + Значение0);     // Выведет: 35
Сообщить("Значение для ключа '200': " + Значение200); // Выведет: 30
Сообщить("Значение для ключа '800': " + Значение800); // Выведет: 5

Также можно использовать метод Получить() объекта Соответствие, что иногда может быть удобнее для цепочного вызова:


// Альтернативный способ доступа
Значение800_ЧерезПолучить = Ответ.Получить("distribution").Получить("800");
Сообщить("Значение для ключа '800' (через Получить): " + Значение800_ЧерезПолучить); // Выведет: 5

Схожая проблема: ошибка "недопустимое имя свойства #value" при работе с XDTO

В рамках обсуждения на форуме пользователи также упоминали схожую проблему, когда при работе с пакетами XDTO и их сериализацией/десериализацией в JSON возникает ошибка "недопустимое имя свойства #value". Эта ситуация подтверждает наш вывод о проблемах Структуры с некоторыми ключами.

Когда объекты XDTO сериализуются в JSON, платформа 1С может добавлять специальные свойства, такие как #type (для указания типа XDTO-объекта) и #value (для значения, если это простой контент или текстовый узел XDTO). Если полученный таким образом JSON-файл затем пытаются прочитать обратно в Структуру, свойство #value будет расценено как недопустимое имя для свойства Структуры, вызывая описанную ошибку.


// Пример кода, вызывающего ошибку с #value при чтении в Структуру
// (гипотетический код, демонстрирующий проблему)
// ... создание МойОбъектXDTO ...
Запись = Новый ЗаписьJSON;
ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Unix);
Запись.УстановитьСтроку(ПараметрыЗаписи);
ФабрикаXDTO.ЗаписатьJSON(Запись, МойОбъектXDTO);
ДанныеJSON = Запись.Закрыть();

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

// Этот вызов вызовет ошибку "недопустимое имя свойства #value"
// если ДанныеJSON содержит ключ #value и ПрочитатьJSON пытается создать Структуру
стСтруктураСхемы = ПрочитатьJSON(обЧтениеJSON);

Решение этой проблемы абсолютно такое же: необходимо читать такой JSON в Соответствие, используя тот же второй параметр Истина:


// Корректное чтение JSON с потенциальными ключами типа #value
обЧтениеJSON = Новый ЧтениеJSON;
обЧтениеJSON.УстановитьСтроку(ДанныеJSON);
стСоответствиеСхемы = ПрочитатьJSON(обЧтениеJSON, Истина);

// Доступ к значению #value будет выглядеть так:
Если стСоответствиеСхемы.Свойство("#value") Тогда
    Сообщить("Значение XDTO: " + стСоответствиеСхемы["#value"]);
КонецЕсли;

Лучшие практики и рекомендации

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

  1. Всегда используйте ПрочитатьJSON(ЧтениеJSON, Истина): Это самый надежный и универсальный подход при чтении JSON в 1С. Он гарантирует, что все JSON-объекты будут преобразованы в Соответствия, что позволяет корректно обрабатывать любые валидные ключи JSON, независимо от их формата.
  2. Используйте Соответствие для доступа к данным: После чтения JSON в Соответствие, обращайтесь к его элементам через квадратные скобки (МоеСоответствие["Ключ"]) или метод Получить() (МоеСоответствие.Получить("Ключ")).
  3. Будьте внимательны к иерархии: Если JSON содержит вложенные объекты, каждый из них также будет прочитан как Соответствие. Вам потребуется последовательно обращаться к этим вложенным Соответствиям.
  4. Избегайте ручной модификации JSON-строки: Хотя теоретически возможно вручную модифицировать исходную JSON-строку, заменяя недопустимые ключи на разрешенные (например, "800" на "Ключ800"), этот подход крайне не рекомендуется. Он менее надежен, более подвержен ошибкам, и может привести к некорректной интерпретации данных. Использование Соответствия – это стандартное и корректное решение, соответствующее идеологии 1С.
  5. Рассмотрите потоковое чтение для больших файлов: Для очень больших JSON-документов или в случаях, когда требуется особая гибкость, 1С предлагает потоковую технику работы с JSON, которая позволяет последовательно читать данные без полной загрузки всего документа в память. Этот подход дает больше контроля над процессом обработки, но требует более сложной реализации и, как правило, не является необходимым для типичных задач обмена данными, которые можно автоматизировать с помощью регулярной синхронизации баз по расписанию.

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

← На главную