Импорт XML-схемы в XDTO-пакет и работа с ним из кода 1С 8.3
Содержание
Чтобы добавить XDTO пакет в 1С, откройте Конфигуратор, в дереве метаданных разверните Общие → XDTO-пакеты, щёлкните правой кнопкой по ветке и выберите Импорт XML-схемы..., укажите файл .xsd. Затем сохраните конфигурацию и обновите конфигурацию базы данных (F7) — без этого код в режиме Предприятия пакета не увидит.
Частое заблуждение — что пакет нужно «создавать руками», описывая каждый тип. Почти всегда это лишнее: партнёр по интеграции даёт XSD, а платформа сама строит из неё типы. Руками пакет собирают, только если схемы нет вовсе. Второе заблуждение — что код обращается к пакету по имени из дерева метаданных. Нет, обращение идёт по URI пространства имён и имени типа.
Порядок действий одинаков для любой конфигурации на платформе 8.3: БП, ЗУП, УТ или собственной разработки.
Что проверить в XSD-схеме перед импортом
Половина проблем с XDTO возникает до нажатия кнопки «Импорт». Откройте схему в любом текстовом редакторе и посмотрите на корневой элемент xs:schema.
📌 Что найти в файле:
- 🔹
targetNamespace— пространство имён. Это главный идентификатор, по нему вы будете получать типы из кода. Запишите его. - 🔹
xs:import— ссылки на другие схемы с другим пространством имён. Каждую такую схему придётся импортировать отдельным пакетом и раньше основной. - 🔹
xs:include— подключение файлов с тем же пространством имён. Их удобнее заранее объединить с основной схемой в один файл. - 🔹
elementFormDefault— влияет на то, будут ли вложенные элементы записываться с префиксом пространства имён. Значениеqualifiedвстречается в обменах с госсистемами чаще всего. - 🔹 Корневые элементы (
xs:elementверхнего уровня) и именованные типы (xs:complexType name="..."). Они станут глобальными свойствами и типами пакета.
Если партнёр прислал архив из десятка XSD, начните с файла, который ни от кого не зависит (в нём нет xs:import), и двигайтесь вверх по цепочке. Нарисуйте на листке, какая схема импортирует какую, — так проще не ошибиться с порядком.
Проверьте и кодировку: схема должна быть в UTF-8 или иметь корректный заголовок <?xml version="1.0" encoding="..."?>. Файл, сохранённый в другой кодировке без заголовка, даст кракозябры в документации к типам, а иногда и ошибку разбора.
Как добавить XDTO-пакет через Конфигуратор
Перед изменением конфигурации сделайте резервную копию: Администрирование → Выгрузить информационную базу в Конфигураторе сохранит файл .dt.
Шаг 1. Откройте конфигурацию для изменения
- Запустите базу в режиме Конфигуратора.
- Откройте дерево:
Конфигурация → Открыть конфигурацию. - Если конфигурация типовая и стоит на поддержке, включите возможность изменения:
Конфигурация → Поддержка → Настройка поддержки. Альтернатива без снятия с поддержки — фабрика из схемы прямо в коде (раздел ниже).
Шаг 2. Импортируйте схему
- В дереве метаданных раскройте ветку
Общие. - Правой кнопкой по
XDTO-пакеты→Импорт XML-схемы.... - Выберите файл
.xsdи подтвердите. - Появится новый пакет. Платформа заполнит его типами, свойствами и ссылками на импортированные пространства имён.
Шаг 3. Проверьте свойства пакета
Откройте палитру свойств пакета (Alt+Enter). Поле «Пространство имен» должно совпадать с targetNamespace из схемы. Имя пакета можно переименовать во что-то понятное, например ОбменЗаказыПартнер: на код это не влияет.
Шаг 4. Сохраните и обновите базу
Нажмите F7 — «Обновить конфигурацию
базы данных». Структура таблиц от XDTO-пакета не меняется, поэтому монопольный доступ для этой операции обычно не нужен. Но пользователям, которые уже работают, придётся перезапустить сеанс, чтобы увидеть изменения.
Быстрая проверка, что пакет подхватился: в режиме Предприятия запустите любую внешнюю обработку и в её серверной процедуре выполните Сообщить(ФабрикаXDTO.Тип("http://example.ru/orders", "Order") <> Неопределено). Если вывелось Да, тип доступен коду.
Если схема импортирует другую, а зависимый пакет ещё не загружен, типы со ссылками на чужое пространство имён окажутся неразрешёнными. Загрузите сначала базовые схемы, потом основную.
Пространства имён, префиксы и зависимые пакеты
В XDTO всё держится на паре «URI пространства имён + имя». Тип Order из http://example.ru/orders и тип Order из http://example.ru/invoices — два разных типа, хотя имена совпадают.
Как платформа связывает пакеты
Если схема содержит xs:import, в импортированном пакете появляется элемент «Импорт» с URI зависимого пространства имён. Сам зависимый пакет должен лежать в той же конфигурации. Посмотреть, что получилось, можно, раскрыв пакет в дереве: импорты, типы значений, типы объектов и глобальные свойства отображаются отдельными узлами.
Обновлять схему лучше так:
- Импортируйте новую версию XSD как новый пакет.
- Убедитесь, что URI в нём такой же, как в старом.
- Удалите старый пакет и при желании дайте новому прежнее имя.
Код при этом переписывать не придётся: он ссылается на URI, а не на имя объекта метаданных.
Двух пакетов с одинаковым пространством имён в одной конфигурации быть не должно. Иначе нельзя однозначно сказать, какой тип вернёт фабрика.
Почему в XML появляются префиксы d1p1, d2p1
При записи фабрика сама выбирает префиксы, например d1p1:. Для XML-парсера это нормально: значение имеет URI, а не буквы префикса. Если система-получатель жёстко ждёт конкретный префикс (такое бывает у самописных приёмников), задайте соответствие методом ЗаписатьСоответствиеПространстваИмен(Префикс, URI) объекта ЗаписьXML. Метод действует на элемент, начало которого только что записано, и на его потомков. Поэтому корневой элемент в таком случае пишут вручную через ЗаписатьНачалоЭлемента, объявляют префиксы, а вложенные объекты выводят фабрикой.
Типы значений, типы объектов и списки
В пакете два вида типов, и путать их нельзя.
| Вид в пакете | Что описывает в XSD | Как выглядит в коде |
|---|---|---|
| Тип значения | простой тип: строка с ограничением длины, перечисление, шаблон | обычное значение 1С: Строка, Число, Дата, Булево |
| Тип объекта | составной тип: xs:complexType с элементами и атрибутами | ОбъектXDTO со свойствами |
| Свойство с верхней границей −1 | maxOccurs="unbounded" | СписокXDTO |
У каждого свойства есть важные характеристики: нижняя и верхняя граница (сколько раз элемент может встречаться), признак «Возможно пустое» (nillable) и форма — элемент, атрибут или текст.
Создание объекта и заполнение свойств
URI = "http://example.ru/orders";
ТипЗаказ = ФабрикаXDTO.Тип(URI, "Order");
ТипСтрока = ФабрикаXDTO.Тип(URI, "OrderLine");
Заказ = ФабрикаXDTO.Создать(ТипЗаказ);
Заказ.Number = "А-1025";
Заказ.Date = ТекущаяДатаСеанса();
Строка = ФабрикаXDTO.Создать(ТипСтрока);
Строка.Sku = "100-200";
Строка.Quantity = 3;
Заказ.Line.Добавить(Строка);
Заказ.Проверить(); // исключение, если объект не соответствует схеме
Здесь Line — свойство с maxOccurs="unbounded", поэтому к нему обращаются как к списку: Добавить(), Количество(), Получить(Индекс).
Если свойство в схеме описано как одиночное, а вы вызываете у него Добавить(), получите ошибку. И наоборот: списку нельзя присвоить значение через =. Сверяйте верхнюю границу свойства в пакете.
Когда имя свойства неудобно
Имя в XSD может содержать дефис или совпадать с ключевым словом. Тогда вместо точки используйте методы Установить("имя-свойства", Значение) и Получить("имя-свойства"). Проверить, есть ли свойство у типа, можно так: Заказ.Свойства().Получить("Comment") <> Неопределено.
Запись объекта XDTO в XML и чтение обратно
Сериализация — это превращение ОбъектXDTO в текст XML. Десериализация — обратный путь.
Запись в строку
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку("UTF-8");
ФабрикаXDTO.ЗаписатьXML(Запись, Заказ, "Order", URI, , НазначениеТипаXML.Неявное);
ТекстXML = Запись.Закрыть();
Имя корневого элемента и URI лучше передавать явно. Параметр НазначениеТипаXML.Неявное убирает атрибут xsi:type у корня: многие приёмники его не ждут и ругаются.
Для записи в файл вместо УстановитьСтроку вызовите ОткрытьФайл(ПутьКФайлу, "UTF-8"), а в конце тот же Закрыть().
Чтение из строки
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(ТекстXML);
Заказ = ФабрикаXDTO.ПрочитатьXML(Чтение, ФабрикаXDTO.Тип(URI, "Order"));
Чтение.Закрыть();
Для Сч = 0 По Заказ.Line.Количество() - 1 Цикл
Строка = Заказ.Line.Получить(Сч);
Сообщить(Строка.Sku + ": " + Формат(Строка.Quantity, "ЧГ=0"));
КонецЦикла;
Тип во втором параметре ПрочитатьXML указывать полезно: так фабрика точно знает, во что превращать корень, даже если в XML нет xsi:type.
XDTO-пакеты и сериализация объектов 1С
Не путайте две задачи. Пакет из XSD нужен для обмена в чужом формате. Для выгрузки справочников и документов 1С «как есть» используется СериализаторXDTO со встроенными пространствами имён платформы — там свой пакет импортировать не нужно.
XDTO без изменения конфигурации: фабрика из XSD в коде
Этого раздела часто не хватает в инструкциях, хотя он экономит время на типовых базах. Если снимать конфигурацию с поддержки нельзя, постройте фабрику из файла схемы в момент выполнения:
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ПутьКXSD);
ДокументDOM = (Новый ПостроительDOM).Прочитать(Чтение);
Чтение.Закрыть();
Схема = (Новый ПостроительСхемXML).СоздатьСхемуXML(ДокументDOM);
НаборСхем = Новый НаборСхемXML;
НаборСхем.Добавить(Схема);
МояФабрика = Новый ФабрикаXDTO(НаборСхем);
ТипЗаказ = МояФабрика.Тип("http://example.ru/orders", "Order");
Дальше работайте с МояФабрика так же, как с глобальной ФабрикаXDTO: Создать, ЗаписатьXML, ПрочитатьXML. Если схем несколько, добавьте в НаборСхем все, начиная с базовых.
Сравнение подходов:
| Способ | Когда подходит | Минусы |
|---|---|---|
| Импорт в Конфигураторе | своя или снятая с поддержки конфигурация, постоянный обмен | правка метаданных, обновление базы |
| Фабрика из XSD в коде | типовая на поддержке, схема часто меняется | схему нужно хранить (макет, файл) и строить фабрику при каждом вызове |
WSПрокси.ФабрикаXDTO | обмен через SOAP-сервис с WSDL | только для веб-сервисов |
Для SOAP пакет вообще можно не импортировать. Схемы типов приходят внутри WSDL, и у объекта WSПрокси есть своя фабрика — Прокси.ФабрикаXDTO. Типы для параметров операций берите из неё.
Схему удобно хранить в макете обработки или общем макете типа «Двоичные данные» и перед построением фабрики записывать во временный файл.
Ошибки при подключении и использовании XDTO-пакетов
Большинство сбоев сводится к трём причинам: неверный URI, не тот тип свойства и XML, который не соответствует схеме.
Ещё один источник путаницы — дата. Если в схеме тип xs:date, а вы присваиваете дату со временем, в XML время отбросится. При xs:dateTime без указания часового пояса получатель может трактовать время по-своему. Договоритесь с партнёром о формате заранее.
Частые вопросы
Можно ли посмотреть XSD уже загруженного пакета?
Экспорт XML-схемы.... Платформа сохранит схему, которую построила по пакету. Её удобно отправить партнёру для сверки.Нужно ли переписывать код, если переименовать XDTO-пакет?
ФабрикаXDTO ищет типы по URI пространства имён и имени типа. Имя объекта метаданных в коде не участвует.Чем ФабрикаXDTO отличается от СериализаторXDTO?
Работает ли XDTO в веб-клиенте?
&НаСервере, а клиенту возвращайте готовую строку или результат разбора.Можно ли создать пакет без XSD?
XDTO-пакеты → Добавить, затем вручную добавить типы объектов и свойства. Но для обмена с внешней системой надёжнее получить от неё схему, иначе расхождения всплывут уже на реальных данных.