При разработке интеграционных решений, веб-сервисов или мобильных приложений на платформе 1С часто возникает задача передачи структуры данных. Если пакет XDTO редактируется в основной конфигурации, ручной экспорт схемы через конфигуратор и последующая вставка в макеты занимают много времени. Разберем, как полностью автоматизировать этот процесс и выгрузить схему XSD программно прямо из встроенного языка.
Для программного получения схемы XSD в режиме 1С:Предприятие используется связка специализированных объектов платформы: ФабрикаXDTO, СхемаXML, ЗаписьDOM и ЗаписьXML.
Проанализируем базовый алгоритм по шагам:
ЭкспортСхемыXML() у глобальной фабрики ФабрикаXDTO (или созданной динамически). В качестве параметра передается строка с URI пространства имен пакета. Метод возвращает объект НаборСхемXML.СхемаXML из полученного набора вызываем метод ОбновитьЭлементDOM(). Это обязательное действие, формирующее актуальное дерево DOM перед записью.ЗаписьDOM выгружаем СхемаXML.ДокументDOM в поток объекта ЗаписьXML, настроенного на файл или на строку.Рассмотрим пример функции, которая принимает URI пространства имен пакета и возвращает готовую схему в виде текстовой строки XML:
Функция ПолучитьТекстСхемыXSD(URIПространстваИмен) Экспорт
// 1. Получаем набор схем для указанного пространства имен
НаборСхем = ФабрикаXDTO.ЭкспортСхемыXML(URIПространстваИмен);
Если НаборСхем.Количество() = 0 Тогда
ВызватьИсключение "Схема для пространства имен " + URIПространстваИмен + " не найдена!";
КонецЕсли;
СхемаXML = НаборСхем.Получить(0);
СхемаXML.ОбновитьЭлементDOM();
// 2. Инициализируем запись XML в строковую переменную
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
// 3. Выполняем запись DOM-модели схемы
ЗаписьDOM = Новый ЗаписьDOM;
ЗаписьDOM.Записать(СхемаXML.ДокументDOM, ЗаписьXML);
Возврат ЗаписьXML.Закрыть();
КонецФункции
Если требуется сохранить схему в виде отдельного физического файла (например, для передачи по FTP, отправки во внешнюю систему или сохранения во временный каталог), модифицируем запись в поток файла:
Процедура ВыгрузитьСхемуXSDВФайл(URIПространстваИмен, ПутьКФайлу) Экспорт
НаборСхем = ФабрикаXDTO.ЭкспортСхемыXML(URIПространстваИмен);
Если НаборСхем.Количество() = 0 Тогда
ВызватьИсключение "Пакет XDTO с URI " + URIПространстваИмен + " не найден в фабрике.";
КонецЕсли;
СхемаXML = НаборСхем.Получить(0);
СхемаXML.ОбновитьЭлементDOM();
ЗаписьXML = Новый ЗаписьXML;
ПараметрыЗаписи = Новый ПараметрыЗаписиXML("UTF-8", "1.0", Ложь);
ЗаписьXML.ОткрытьФайл(ПутьКФайлу, ПараметрыЗаписи);
ЗаписьDOM = Новый ЗаписьDOM;
ЗаписьDOM.Записать(СхемаXML.ДокументDOM, ЗаписьXML);
ЗаписьXML.Закрыть();
КонецПроцедуры
Обратите внимание: если ваш пакет XDTO импортирует типы из других пользовательских пакетов XDTO, метод ЭкспортСхемыXML() вернет объект НаборСхемXML, содержащий более одного элемента СхемаXML. В такой ситуации необходимо обойти всю коллекцию в цикле и сохранить каждую схему в отдельный файл:
Процедура ВыгрузитьВсеЗависимыеСхемы(URIПространстваИмен, КаталогВыгрузки) Экспорт
НаборСхем = ФабрикаXDTO.ЭкспортСхемыXML(URIПространстваИмен);
ЗаписьDOM = Новый ЗаписьDOM;
Для Номер = 0 По НаборСхем.Количество() - 1 Цикл
СхемаXML = НаборСхем.Получить(Номер);
СхемаXML.ОбновитьЭлементDOM();
ИмяФайла = КаталогВыгрузки + "\schema_" + Формат(Номер, "ЧЦ=3; ЧВН=") + ".xsd";
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ИмяФайла, Новый ПараметрыЗаписиXML("UTF-8"));
ЗаписьDOM.Записать(СхемаXML.ДокументDOM, ЗаписьXML);
ЗаписьXML.Закрыть();
КонецЦикла;
КонецПроцедуры
Чтобы избежать необходимости вручную встраивать макеты схемы в конфигурацию мобильного приложения при каждом изменении состава полей, можно применить динамическое создание фабрики XDTO:
СоздатьФабрикуXDTO(ИмяФайлаСхемы) создается динамическая фабрика.Фабрика.ПрочитатьXML() или формирования исходящих через Фабрика.ЗаписатьXML() без добавления пакета в дерево метаданных.Вместо экспорта в формат XSD платформенные механизмы 1С позволяют работать напрямую с моделью XDTO:
ФабрикаXDTO.ЭкспортМоделиXDTO(URIПространстваИмен). Результатом вызова является ОбъектXDTO, который можно сериализовать в XML стандартным вызовом ФабрикаXDTO.ЗаписатьXML().НоваяФабрика = Новый ФабрикаXDTO(ОбъектМодели).Такой подход полностью исключает ручную работу с конфигуратором и позволяет централизованно обновлять форматы обмена данными "на лету".