Разработка и Конфигурация · 9 мин
Как сохранить XDTO в файл в 1С: пошаговая инструкция
Как сохранить XDTO-пакет и объект XDTO в файл в 1С: запись XML через ЗаписьXML, сериализация XDTO, примеры кода, типичные ошибки и проверка результата.
Под «сохранением XDTO в файл» в 1С обычно понимают две разные задачи. Первая — выгрузить объект XDTO (значение, полученное из фабрики XDTO) в XML-файл, то есть выполнить сериализацию. Вторая — сохранить саму схему XDTO-пакета в XSD-файл, например для передачи подрядчику или для проверки внешним валидатором. Обе задачи решаются штатными средствами платформы без внешних компонент.
Основной инструмент — объект ЗаписьXML совместно с методами фабрики XDTO: ФабрикаXDTO.ЗаписатьXML() для объектов и ФабрикаXDTO.ЭкспортСхемыXML() для схем. Ниже разобраны оба сценария с готовым кодом, вариантами записи в строку и в файл, а также типичные ошибки, из-за которых файл получается пустым или битым.
Что именно вы сохраняете: объект XDTO или схему пакета
Прежде чем писать код, определите, что является источником данных. Объект XDTO — это экземпляр данных в памяти, созданный через ФабрикаXDTO.Создать() или прочитанный из XML. Его сохранение — это сериализация в XML-документ. Схема пакета XDTO — это описание типов из раздела «XDTO-пакеты» в конфигураторе; её сохранение — это экспорт в XSD.
От этого зависит весь дальнейший код: для объекта используется ЗаписатьXML, для схемы — ЭкспортСхемыXML. Путаница между этими задачами — самая частая причина вопросов: разработчик пытается «записать пакет» методом, предназначенным для объектов, и получает ошибку несоответствия типов.
Сохранение объекта XDTO в XML-файл
Стандартный сценарий: создать объект ЗаписьXML, открыть файл, записать объект через фабрику и закрыть запись. Именно вызов Закрыть() физически формирует файл — пропуск этого вызова оставляет файл пустым или незавершённым.
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл("C:\Temp\data.xml", "UTF-8");
Запись.ЗаписатьОбъявлениеXML();
ФабрикаXDTO.ЗаписатьXML(Запись, МойОбъектXDTO);
Запись.Закрыть();
Если объект хранится в типизированном пакете с пространством имён, фабрика сама подставит нужные префиксы пространств. При необходимости можно передать назначение типа и форму явно, но в большинстве случаев достаточно двух аргументов.
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл(ИмяФайла, "UTF-8");
Запись.ЗаписатьОбъявлениеXML();
ФабрикаXDTO.ЗаписатьXML(Запись, ОбъектXDTO);
Запись.Закрыть();Вариант: сначала в строку, потом в файл
Когда результат нужно дополнительно обработать (например, отправить в HTTP-запросе и одновременно сохранить копию), удобнее записать XML в строку, а затем сохранить её через ЗаписьТекста:
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку("UTF-8");
ФабрикаXDTO.ЗаписатьXML(Запись, МойОбъектXDTO);
ТекстXML = Запись.Закрыть();
Документ = Новый ЗаписьТекста("C:\Temp\data.xml", КодировкаТекста.UTF8);
Документ.Записать(ТекстXML);
Документ.Закрыть();
Обратите внимание: при записи в строку метод Закрыть() возвращает готовый XML-текст. Это удобно для отладки — строку можно вывести в сообщение или журнал до записи на диск.
Экспорт схемы XDTO-пакета в XSD-файл
Если требуется сохранить саму схему пакета, используется метод ЭкспортСхемыXML глобальной фабрики. Он принимает URI пространства имён пакета и возвращает объект ЗаписьXML-совместимого результата — точнее, схему в виде, которую нужно записать:
Схема = ФабрикаXDTO.ЭкспортСхемыXML("http://mycompany.ru/package");
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл("C:\Temp\schema.xsd", "UTF-8");
Запись.ЗаписатьОбъявлениеXML();
Схема.Записать(Запись);
Запись.Закрыть();
URI пространства имён должен точно совпадать с указанным в свойствах пакета в конфигураторе, включая регистр и слэши. При несовпадении метод вернёт пустой результат или вызовет исключение. Если пакет импортирует другие пакеты, экспортируется только указанное пространство имён — зависимые схемы выгружайте отдельно.
Сохранение произвольного значения через сериализатор XDTO
Третий сценарий — сохранить в XML обычное значение 1С (ссылку на объект, структуру, таблицу значений), для которого нет XDTO-пакета. Здесь помогает СериализаторXDTO:
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл("C:\Temp\value.xml", "UTF-8");
Запись.ЗаписатьОбъявлениеXML();
Сериализатор = Новый СериализаторXDTO(ФабрикаXDTO);
Сериализатор.ЗаписатьXML(Запись, МоеЗначение);
Запись.Закрыть();
Такой файл можно прочитать обратно тем же сериализатором методом ПрочитатьXML. Это рабочий способ обмена данными между информационными базами с одинаковой конфигурацией. Ограничение: не все типы сериализуются (например, картинки и некоторые служебные объекты требуют отдельной обработки), а ссылки при переносе между разными базами теряют смысл.
Сравнение вариантов
Для объектов XDTO, созданных по схеме пакета. Контроль типов и пространств имён, результат соответствует XSD.
Для выгрузки самой схемы пакета в XSD-файл. Не подходит для данных.
Для произвольных значений 1С без XDTO-пакета: ссылок, структур, таблиц. Не для обмена с внешними системами по контракту.
Выбор кодировки и пути к файлу
Кодировка задаётся вторым параметром ОткрытьФайл(). Для обмена с внешними системами стандарт де-факто — UTF-8. Если принимающая сторона требует UTF-16 или windows-1251, укажите это явно: несовпадение кодировки в объявлении XML и фактической кодировке файла делает документ невалидным для парсера получателя.
По путям учитывайте контекст выполнения. Код, выполняемый на сервере 1С, пишет в файловую систему сервера, а не клиентского компьютера. Каталог C:\Temp на клиенте и на сервере — разные места. Для клиент-серверного режима либо используйте каталог, доступный серверу, либо передавайте данные на клиента через временное хранилище (ПоместитьВоВременноеХранилище) и сохраняйте уже там.
Проверка результата и типичные ошибки
После записи откройте файл в текстовом редакторе или браузере. Признаки корректного результата: наличие объявления <?xml version="1.0" encoding="UTF-8"?>, корневой элемент с ожидаемым пространством имён, файл не нулевого размера. Дополнительно файл можно прочитать обратно через ЧтениеXML и ФабрикаXDTO.ПрочитатьXML() — если чтение проходит без исключения, сериализация выполнена корректно.
Как проверить результат
Файл существует и имеет ненулевой размер
Файл 0 байт — вероятно, не вызван Закрыть()
Объявление XML с корректной кодировкой
Объявление отсутствует или кодировка не совпадает с фактической
ФабрикаXDTO.ПрочитатьXML читает файл без исключений
Ошибка разбора — XML повреждён или не завершён
FAQ
Как сохранить объект XDTO в файл на клиенте, если код выполняется на сервере?
Сформируйте XML на сервере, поместите строку или двоичные данные во временное хранилище, верните адрес хранилища на клиент и там запишите содержимое в файл через ЗаписьТекста или ЗаписьДанных. Прямая запись по локальному пути из серверного кода невозможна.
Почему после записи файл пустой?
Чаще всего не вызван метод Закрыть() у объекта ЗаписьXML — данные остаются в буфере. Реже причина в исключении, перехваченном пустым блоком Попытка/Исключение, из-за чего запись прерывается незаметно.
Можно ли сохранить XDTO в файл без объявления XML?
Да — просто не вызывайте ЗаписатьОбъявлениеXML(). Это допустимо, если фрагмент будет встраиваться в другой документ. Для самостоятельного файла объявление лучше оставить: без него получатель может неверно определить кодировку.
Как выгрузить схему всех пакетов конфигурации разом?
Штатного метода массового экспорта нет. Переберите пакеты через ФабрикаXDTO.Пакеты, для каждого получите URI пространства имён и вызовите ЭкспортСхемыXML в цикле, сохраняя каждый результат в отдельный XSD-файл.
Чем отличается ЗаписатьXML фабрики от СериализатораXDTO?
Фабрика работает с объектами XDTO, созданными по схеме пакета, и гарантирует соответствие XSD. СериализаторXDTO преобразует произвольные значения 1С (ссылки, структуры, таблицы значений) в XML без схемы — это удобно для обмена между своими базами, но не для интеграции по контракту с внешними системами.
Что важно запомнить
Объект XDTO сохраняется через ЗаписьXML + ФабрикаXDTO.ЗаписатьXML, схема пакета — через ЭкспортСхемыXML, произвольные значения — через СериализаторXDTO. Всегда вызывайте Закрыть(), следите за кодировкой и помните, что серверный код пишет в файловую систему сервера.