В процессе разработки интеграций на 1С часто возникает необходимость обработки данных формата JSON. Одной из частых ошибок, с которой сталкиваются разработчики, является попытка использовать ФабрикаXDTO для десериализации произвольного JSON-объекта. В этой статье мы подробно разберем, почему возникает ошибка при вызове метода ПрочитатьJSON, и какие подходы являются наиболее правильными и профессиональными.
Метод ФабрикаXDTO.ПрочитатьJSON был спроектирован для работы со сложными структурами, описанными в XSD-схемах. Когда мы вызываем этот метод, ФабрикаXDTO ожидает, что структура JSON строго соответствует определенному Типу из XDTO-пакета. Если структура данных в JSON отличается от ожидаемой, или если мы пытаемся «скармливать» Фабрике части объекта по очереди, происходит нарушение процесса разбора.
Ключевая ошибка автора заключалась в попытке прочитать поля JSON по отдельности. Каждый вызов метода ПрочитатьJSON перемещает указатель (курсор) внутри объекта ЧтениеJSON. После первого чтения позиция внутри потока смещается, и при последующих вызовах Фабрика просто «теряется», не понимая, где начинается и заканчивается объект, так как не видит всей структуры целиком.
Если специфика задачи требует ручного управления позицией ЧтениеJSON, важно помнить о том, что каждый вызов Прочитать() переводит курсор на следующий узел (начало свойства или конец объекта). Чтобы корректно прочитать структуру, необходимо явно пропускать элементы, которые не являются целевыми значениями. Рассмотрим пример кода, который позволяет считать данные, последовательно перемещаясь по узлам:
в1="{
| ""#value"": 0,
| ""Don1"": 1,
| ""Don2"": 2
|}";
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(в1);
тд = ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "double");
Чтение.Прочитать(); // пропускаем начало объекта
Чтение.Прочитать(); // пропускаем начало свойства "#value"
Пустышка = ФабрикаXDTO.ПрочитатьJSON(Чтение, тд);
Чтение.Прочитать(); // пропускаем начало свойства "Don1"
Число1 = ФабрикаXDTO.ПрочитатьJSON(Чтение, тд);
Чтение.Прочитать(); // пропускаем начало свойства "Don2"
Число2 = ФабрикаXDTO.ПрочитатьJSON(Чтение, тд);
Чтение.Закрыть();
Однако, данный подход крайне хрупок. Он зависит от жесткого порядка полей в JSON, который, согласно спецификации формата, не гарантируется. Любое изменение порядка или добавление нового поля приведет к тому, что код начнет считывать не те данные, что приведет к логическим ошибкам или падению системы.
Разберемся, почему использование ФабрикаXDTO для простых структур является «забиванием гвоздей микроскопом». Начиная с версии 1С 8.3.6, платформа предоставляет встроенный, эффективный механизм для работы с JSON. Вместо попыток подогнать произвольный JSON под XDTO-типы, используйте метод ПрочитатьJSON глобального контекста.
Этот метод считывает весь объект целиком и преобразует его в Структуру или Соответствие, что гораздо надежнее и быстрее.
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(в1);
// Читаем все данные сразу в структуру
Данные = ПрочитатьJSON(Чтение, Истина);
Чтение.Закрыть();
// Теперь работаем с данными как с обычной структурой 1С
Для Каждого КлючИЗначение Из Данные Цикл
Сообщить("Свойство: " + КлючИЗначение.Ключ + " Значение: " + КлючИЗначение.Значение);
КонецЦикла;
Структуры позволяет легко работать с данными, даже если их структура меняется или в них добавляются новые поля.Структуру работает значительно быстрее, так как платформа не выполняет ресурсоемкие проверки соответствия XSD-схемам.ФабрикаXDTO оправдано только в узких задачах — например, при обмене данными между конфигурациями 1С, где обе стороны строго придерживаются одного и того же XDTO-пакета.Подведем итог: Если вы получаете JSON из стороннего API, всегда используйте ПрочитатьJSON(ЧтениеJSON). Это избавит вас от проблем с позиционированием курсора и ошибками приведения типов. Если же вы все-таки используете ФабрикаXDTO, убедитесь, что вы описываете весь объект целиком в XDTO-пакете и загружаете его за один вызов метода, чтобы не зависеть от порядка следования ключей в файле.