К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как записать XDTO в XML в 1С: пошаговое руководство

Как записать объект XDTO в XML в 1С: сериализатор XDTO, запись в файл и строку, фабрика XDTO, примеры кода, типичные ошибки и проверка результата.

Запись объекта XDTO в XML — одна из базовых задач при интеграции 1С с внешними системами: обмене по веб-сервисам, выгрузке документов в форматах ФНС, формировании файлов для банков и контрагентов. Платформа 1С предоставляет для этого объект «СериализаторXDTO», который преобразует значения и объекты XDTO в узлы XML с учётом схемы, описанной в пакете XDTO.

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

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

Что понадобится: фабрика XDTO и пакет схемы

Прежде чем что-то записывать, нужна фабрика XDTO — объект, который знает схему ваших данных. Если пакет XDTO добавлен в конфигурацию (ветка «Общие → XDTO-пакеты» в конфигураторе), глобальная фабрика уже содержит его типы, и достаточно обращения к ФабрикаXDTO. Если схема лежит во внешнем файле XSD, фабрику нужно построить вручную: прочитать схему через ЧтениеXML с построителем схем и создать фабрику методом СоздатьФабрикуXDTO.

Проверить, что тип доступен, можно простым способом: попробовать получить его через ФабрикаXDTO.Тип("URIПространстваИмен", "ИмяТипа"). Если тип не найден, платформа выдаст исключение — это первый сигнал, что пакет не подключён или пространство имён указано неверно. URI пространства имён должен совпадать с тем, что указан в схеме, символ в символ, включая регистр и завершающие слэши.

Создание и заполнение объекта XDTO

Объект XDTO создаётся через фабрику: сначала получаете тип объекта, затем вызываете ФабрикаXDTO.Создать(Тип). Свойства заполняются по именам, как они объявлены в схеме. Для вложенных объектов создаются свои экземпляры соответствующих типов, для списков используется свойство-список, в которое элементы добавляются методом Добавить().

ТипДокумент = ФабрикаXDTO.Тип("http://example.org/doc", "Документ");

Документ = ФабрикаXDTO.Создать(ТипДокумент);

Документ.Номер = "А-100";

Документ.Дата = ТекущаяДатаСеанса();

ТипСтрока = ФабрикаXDTO.Тип("http://example.org/doc", "СтрокаДокумента");

Строка = ФабрикаXDTO.Создать(ТипСтрока);

Строка.Номенклатура = "Товар 1";

Строка.Количество = 5;

Документ.Строки.Добавить(Строка);

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

Если часть данных может отсутствовать, проверяйте заполненность перед установкой свойства или используйте метод Установлено() при чтении. Для необязательных свойств, которые вы сознательно не заполняете, сериализатор просто не выведет соответствующий элемент — это нормальное поведение по схеме.

Запись объекта XDTO в XML-файл

Основной сценарий — запись в файл на диск. Создаётся объект ЗаписьXML, открывается файл с указанием кодировки (обычно UTF-8), затем вызывается метод сериализатора. После записи файл обязательно закрывается.

ЗаписьXML = Новый ЗаписьXML;

ЗаписьXML.ОткрытьФайл("C:\Обмен\document.xml", "UTF-8");

ЗаписьXML.ЗаписатьОбъявлениеXML();

Сериализатор = Новый СериализаторXDTO(ФабрикаXDTO);

Сериализатор.ЗаписатьXML(ЗаписьXML, Документ);

ЗаписьXML.Закрыть();

Порядок записи XDTO в файл
  1. 1
    Убедитесь, что пакет XDTO добавлен в конфигурацию или фабрика построена из XSD-файла
  2. 2
    Создайте объект XDTO через ФабрикаXDTO.Создать() и заполните обязательные свойства
  3. 3
    Создайте ЗаписьXML и откройте файл с нужной кодировкой
  4. 4
    Вызовите СериализаторXDTO.ЗаписатьXML() с передачей объекта
  5. 5
    Закройте ЗаписьXML и проверьте содержимое файла

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

Запись XDTO в строку без файла

Когда XML нужен не как файл, а как строка — например, для отправки в теле HTTP-запроса или сохранения в реквизит объекта, — используется метод УстановитьСтроку() вместо открытия файла. После записи результат забирается методом Закрыть(), который возвращает сформированный текст.

ЗаписьXML = Новый ЗаписьXML;

ЗаписьXML.УстановитьСтроку("UTF-8");

Сериализатор = Новый СериализаторXDTO(ФабрикаXDTO);

Сериализатор.ЗаписатьXML(ЗаписьXML, Документ);

СтрокаXML = ЗаписьXML.Закрыть();

Обратите внимание: при записи в строку объявление XML () добавляется автоматически, если не управлять им вручную. Некоторые принимающие системы требуют конкретную кодировку в объявлении или вообще отсутствие объявления — это регулируется параметрами УстановитьСтроку() и явным вызовом ЗаписатьОбъявлениеXML() либо его пропуском.

Запись произвольных значений 1С и чтение обратно

Сериализатор XDTO умеет записывать не только объекты XDTO, но и обычные значения платформы: ссылки, структуры поддерживаемых типов, значения примитивных типов. Для ссылочных объектов в XML записывается их представление по правилам сериализации (тип и уникальный идентификатор), что используется, например, при обмене между информационными базами 1С.

Обратная операция — чтение — выполняется тем же сериализатором через ПрочитатьXML():

ЧтениеXML = Новый ЧтениеXML;

ЧтениеXML.ОткрытьФайл("C:\Обмен\document.xml");

Сериализатор = Новый СериализаторXDTO(ФабрикаXDTO);

ПрочитанныйОбъект = Сериализатор.ПрочитатьXML(ЧтениеXML);

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

Такая пара «запись–чтение» — самый надёжный способ проверить корректность сериализации: если объект читается обратно без ошибок и его свойства совпадают с исходными, XML сформирован правильно с точки зрения схемы. Проверку стоит выполнять на этапе разработки обмена, прежде чем передавать файлы внешней системе.

Контрольные точки

Как проверить результат

Чтение записанного файла через ПрочитатьXML
Норма

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

Тревожный признак

Ошибка контроля схемы или неожиданный тип результата

Содержимое файла в текстовом редакторе
Норма

Корректное объявление XML, нужные пространства имён, все обязательные элементы на месте

Тревожный признак

Пустые обязательные элементы, неверная кодировка, лишние префиксы

Валидация внешней системой или XSD-валидатором
Норма

Файл проходит проверку принимающей стороной

Тревожный признак

Ошибки валидации по схеме у получателя

Типичные ошибки и их причины

Чаще всего запись падает из-за незаполненных обязательных свойств: сериализатор выполняет контроль по схеме и выдаёт исключение вида «Ошибка проверки данных XDTO». Текст ошибки указывает, какое свойство и в каком типе нарушает схему — начинайте разбор с него, а не с кода записи.

Вторая группа проблем — пространства имён. Если при создании типа указан URI, отличающийся от объявленного в пакете (лишний слэш, другой регистр), тип просто не находится. Третья группа — несовпадение фабрик у объекта и сериализатора, о чём уже говорилось выше. Наконец, ошибки ввода-вывода: отсутствие каталога для файла, недостаток прав, попытка записи в клиентский путь из серверного кода.

Типичные ошибки
01
Не заполнены обязательные свойства объекта — сериализация завершается ошибкой контроля схемы
02
URI пространства имён не совпадает с пакетом XDTO — тип не находится, возникает исключение при создании объекта
03
Объект создан одной фабрикой, сериализатор построен на другой — ошибка несоответствия типов при записи
04
Запись в файл на клиентском пути из серверного кода — файл не создаётся или падает ошибка доступа
05
Не закрыт объект ЗаписьXML — файл остаётся пустым или неполным, данные теряются

Отдельно стоит упомянуть попытки «подправить» XML вручную после сериализации строковыми заменами. Это ломает экранирование спецсимволов и структуру пространств имён. Если нужен нестандартный вид XML, управляйте записью через параметры ЗаписьXML или формируйте документ построчно без XDTO — но тогда ответственность за соответствие схеме ложится на вас.

Альтернативы сериализатору XDTO

XDTO — не единственный способ получить XML из 1С. Если схема не задана или структура документа простая и нестабильная, можно формировать XML напрямую через ЗаписьXML: последовательно записывая элементы и атрибуты. Это гибче, но без контроля по схеме, и валидацию придётся делать отдельно.

Для обмена между базами 1С с типовыми механизмами часто удобнее планы обмена и универсальный формат EnterpriseData, где сериализация уже встроена. Ручная работа с XDTO оправдана, когда формат жёстко задан внешней стороной и есть XSD-схема: именно тогда контроль по схеме экономит время на отладке.

Сравнение подходов

СериализаторXDTO + пакет XDTO

Когда есть XSD-схема от внешней системы. Контроль обязательных полей и типов автоматически, но требует корректного пакета

Прямая запись через ЗаписьXML

Когда схемы нет или структура часто меняется. Полная гибкость, но валидация — ваша задача

Планы обмена / EnterpriseData

Для обмена между базами 1С типовыми данными. Не подходит для произвольных внешних форматов

Итог

Что важно запомнить

Запись XDTO в XML выполняется через СериализаторXDTO.ЗаписатьXML(): объект создаётся и заполняется через ту же фабрику, что передана сериализатору, обязательные свойства должны быть заполнены, а результат проверяется обратным чтением. Для строки используйте УстановитьСтроку(), для файла — ОткрытьФайл() с явным закрытием.

Частые вопросы

Можно ли записать XDTO в XML без пакета XDTO в конфигурации?

Да, если построить фабрику из внешнего XSD-файла: схема читается через ЧтениеXML с построителем схемы, затем создаётся фабрика функцией СоздатьФабрикуXDTO. Дальше работа идёт так же, как с глобальной фабрикой, только сериализатор нужно создавать именно с этой построенной фабрикой.

Почему при записи возникает «Ошибка проверки данных XDTO»?

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

Как убрать объявление XML из строки результата?

При использовании УстановитьСтроку() объявление добавляется автоматически. Если принимающая система его не принимает, можно отрезать первую строку результата программно или формировать документ через прямую ЗаписьXML без вызова ЗаписатьОбъявлениеXML(), контролируя каждый шаг записи.

Как записать список элементов XDTO в XML?

Свойство-список в объекте XDTO заполняется методом Добавить(): создаёте элемент нужного типа через ФабрикаXDTO.Создать(), заполняете его и добавляете в список. При сериализации каждый элемент списка будет записан как отдельный повторяющийся элемент XML — дополнительных действий не требуется.

Чем запись XDTO отличается от ЗаписатьJSON?

Это разные механизмы: СериализаторXDTO работает с XML и схемами XDTO, а ЗаписатьJSON — с форматом JSON и своими правилами преобразования типов. Если внешняя система ждёт XML по XSD-схеме, подходит только XDTO; для REST-сервисов с JSON используется отдельный механизм сериализации JSON.

Можно ли сериализовать ссылку справочника или документа через XDTO?

Да, сериализатор умеет записывать ссылочные значения: в XML попадают тип объекта и его уникальный идентификатор. Такой файл корректно читается обратно в базе с той же конфигурацией, но бесполезен для внешних систем — для них данные нужно сначала преобразовать в объект XDTO с понятной внешней структурой.