Как правильно прочитать XML-файл с помощью XDTO в 1С и избежать типичных ошибок

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

Работа с XML-файлами — одна из самых частых задач при интеграции 1С с внешними системами. Механизм XML Data Transfer Objects (XDTO) является мощным и быстрым инструментом для решения этой задачи. Однако у начинающих разработчиков он часто вызывает трудности. Ошибки вроде «Структура объекта не соответствует типу...» могут поставить в тупик на несколько дней.

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

Постановка задачи и анализ исходной структуры XML

Представим типичную задачу. Нам необходимо прочитать XML-файл, содержащий список клиентов, и загрузить их в справочник 1С. Наш XML-файл имеет следующую структуру:


<catalog>
    <clients>
        <client>Иван Иванов</client>
        <client>Петр Петров</client>
    </clients>
</catalog>

Типичная ошибка новичка — создать в пакете XDTO сразу тип объекта client и попытаться прочитать файл, указав этот тип в качестве ожидаемого. При попытке выполнить код платформа 1С выдаст ошибку: «Ошибка проверки данных XDTO: Структура объекта не соответствует типу...».

Выясним причину этой ошибки. Механизм XDTO не умеет самостоятельно «искать» нужные теги внутри XML-файла в обход его структуры. Чтение XML с использованием конкретного типа XDTO требует, чтобы корневой тег XML-файла строго соответствовал переданному типу. Поскольку наш корневой тег — это <catalog>, то и в схеме XDTO мы обязаны описать всю иерархию, начиная с самого верхнего уровня.

Шаг 1. Проектирование схемы XDTO в конфигураторе

Чтобы успешно прочитать наш файл, нам нужно полностью воссоздать структуру вложенности тегов в пакете XDTO. Давайте разберем по шагам, как настроить типы в конфигураторе 1С:

  1. Создадим новый Пакет XDTO в конфигурации.
  2. Добавим Тип объекта с именем catalog. Внутри него создадим свойство clients.
  3. Добавим второй Тип объекта с именем clients. Внутри него создадим свойство client.
  4. Для свойства client укажем тип данных. Если это просто текст (как в нашем примере), мы можем указать простой тип string из стандартного пространства имен XML-схемы (http://www.w3.org/2001/XMLSchema). Если же внутри тега <client> содержатся другие теги (например, <id> или <phone>), нам потребуется создать отдельный тип объекта client со своими свойствами.

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

Шаг 2. Разбираемся с пространствами имен (URI)

Несоответствие пространств имен — это вторая по популярности причина ошибок при валидации XDTO. Проанализируем правила сопоставления URI:

Помните также, что механизм XDTO крайне чувствителен к регистру. Тег <Client> в XML и свойство client в схеме будут распознаны как абсолютно разные элементы, что приведет к ошибке чтения.

Шаг 3. Написание программного кода для чтения данных

После того как схема настроена, напишем код для чтения файла и получения коллекции клиентов. Разберем этот процесс на практическом примере:


// Укажем URI пространства имен нашего пакета (если оно задано в пакете)
АдресПространстваИмен = "https://www.myproject.ru/xdto";

// Получаем тип самого верхнего (корневого) элемента из фабрики XDTO
ТипФабрикиXDTO = ФабрикаXDTO.Тип(АдресПространстваИмен, "catalog");

// Инициализируем чтение XML-файла
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл("C:\Обмен\clients.xml");

Попытка
    // Читаем весь XML-документ, приводя его к нашему корневому типу catalog
    КаталогДанных = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML, ТипФабрикиXDTO);
    
    // Обращаемся по цепочке свойств к коллекции клиентов
    СписокКлиентов = КаталогДанных.clients.client;
    
    // Переменная "СписокКлиентов" теперь имеет тип СписокXDTO.
    // Обойдем ее в стандартном цикле 1С
    Для Каждого ТекущийКлиент Из СписокКлиентов Цикл
        // Обрабатываем каждого клиента. В нашем случае это просто строка
        ИмяКлиента = ТекущийКлиент;
        Сообщить("Прочитан клиент: " + ИмяКлиента);
        
        // Здесь можно написать код для поиска или создания элемента справочника
    КонецЦикла;

Исключение
    Сообщить("Ошибка при чтении XML: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;

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

Интересная особенность работы со «СписокXDTO»

Рассмотрим важную особенность платформы 1С. В веб-разработке часто встречается ситуация, когда при конвертации XML в JSON один элемент возвращается как объект, а несколько — как массив. Это заставляет разработчиков писать дополнительные проверки на тип данных.

В XDTO всё устроено гораздо строже и удобнее. Если в вашей схеме для свойства client максимальное количество элементов указано как -1, то свойство КаталогДанных.clients.client всегда вернет объект типа СписокXDTO. Это произойдет даже в том случае, если в XML-файле физически присутствует только один клиент или тег вообще пуст. Такой подход гарантирует стабильность вашего кода и защищает его от неожиданных падений.

Альтернативный вариант: чтение без явного указания типа

При вызове метода ФабрикаXDTO.ПрочитатьXML() мы передавали вторым параметром тип корневого элемента. Однако этот параметр можно сделать необязательным, упростив код. Для этого используется механизм глобальных элементов схемы:

  1. Откройте ваш пакет XDTO в конфигураторе.
  2. В самом корне пакета (на том же уровне, где находятся «Типы объектов») добавьте новый Элемент с именем catalog.
  3. В свойствах этого элемента укажите тип — ранее созданный тип объекта catalog.

После этого вы сможете читать XML-файлы одной простой строчкой, не определяя предварительно тип фабрики вручную:

КаталогДанных = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);

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

Лайфхак: автоматическое создание схемы (Импорт XSD)

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

  1. Воспользуйтесь любым бесплатным онлайн-генератором схем XSD по XML-файлу (их легко найти в интернете). Скопируйте туда ваш пример XML, и сервис сгенерирует схему XSD.
  2. Сохраните полученный текст схемы в файл с расширением .xsd.
  3. В конфигураторе 1С перейдите в ветку «Пакеты XDTO», нажмите на нее правой кнопкой мыши и выберите пункт «Импорт схемы XML...».
  4. Укажите сохраненный файл .xsd.

Платформа 1С мгновенно создаст готовый пакет XDTO со всеми необходимыми иерархическими связями, типами данных, правильными ограничениями количества элементов и пространствами имен. Вам останется только написать лаконичный код для чтения данных.

← На главную