Как сформировать XML-файл с данными по XSD-схеме в 1С, используя ФабрикуXDTO?

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

При работе с внешними системами и тестировании http сервисов часто возникает задача выгрузки данных из 1С в формате XML, строго соответствующем предоставленной схеме XSD (также часто применяется выгрузка в формате JSON) — для этого подойдёт универсальная обработка выгрузки в XML и JSON с гибкой настройкой структуры. Эта задача может вызвать вопросы, особенно если нет примера готового XML-файла. В этом поможет анализ структуры метаданных. В этом руководстве мы подробно рассмотрим, как подойти к этой проблеме, используя инструментарий 1С, такой как ФабрикаXDTO и ОбъектыXDTO.

Начнем с того, что схема XSD (XML Schema Definition) описывает структуру XML-документа: какие элементы и атрибуты могут быть, их типы данных, порядок следования, обязательность и количество повторений. Наша задача — "перевести" это описание в объекты 1С, заполнить их данными и затем сериализовать в XML-файл.

1. Подготовка схемы XSD и импорт в 1С

Прежде чем мы начнем работать с XSD-схемой программно, нам необходимо корректно ее обработать и, при необходимости, импортировать в конфигурацию 1С. Иногда XSD-файлы содержат ссылки на другие схемы (секция xsd:import), что может вызвать проблемы при импорте или создании ФабрикиXDTO напрямую из файла. В таком случае, мы рекомендуем выполнить следующие шаги:

  1. Сохраните XSD-файл: Получите XSD-схему (например, по ссылке в браузере, используя "Сохранить как") и сохраните ее на диск с расширением .xsd.
  2. Очистите от внешних ссылок (при необходимости): Откройте сохраненный файл XSD в любом текстовом редакторе (например, Блокнот или Notepad++). Найдите и удалите строки, содержащие секцию <xsd:import>, если они есть и вызывают ошибки при работе с файлом. Важно: Делайте это только в том случае, если вы уверены, что импортируемые схемы не являются критически важными для основной структуры, или если у вас есть все необходимые файлы XSD в одном каталоге и вы планируете создать набор схем.
  3. Импортируйте XSD-схему в конфигурацию 1С:
    1. Откройте вашу конфигурацию в режиме "Конфигуратор".
    2. В дереве объектов конфигурации найдите ветку "XDTO-пакеты".
    3. Щелкните правой кнопкой мыши на этой ветке и выберите пункт "Импорт XML-схемы...".
    4. В открывшемся окне укажите путь к вашему подготовленному XSD-файлу.
    5. После успешного импорта в ветке "XDTO-пакеты" появится новый пакет, содержащий все типы, описанные в вашей схеме. Это позволит нам обращаться к ним по именам пакетов и типов.

Этот шаг является необязательным для программного создания ФабрикиXDTO, но он удобен для визуализации структуры схемы и работы с ней в дальнейшем, если вы планируете использовать эти типы многократно.

2. Создание ФабрикиXDTO из XSD-схемы

Первый программный шаг — это создание объекта ФабрикаXDTO, который будет "знать" о всех типах, определенных в нашей XSD-схеме. ФабрикаXDTO — это центральный объект для работы с XDTO в 1С. Мы можем создать ее либо на основе уже импортированной в конфигурацию схемы, либо непосредственно из файла XSD.

Рассмотрим пример создания ФабрикиXDTO из файла XSD. Этот подход полезен, когда схему не нужно жестко встраивать в конфигурацию, или она часто меняется.


// Пусть Сайт - это путь к файлу XSD.
// Например: Сайт = "C:\МоиСхемы\МояСхема.xsd";
// Создадим фабрику XDTO на основе схемы XML, содержащейся в файле XSD.

// 1. Создадим объект чтения XML по умолчанию.
НовоеЧтениеXML = Новый ЧтениеXML;

// 2. Откроем файл XSD.
// Важно: здесь мы открываем XSD как обычный XML-файл для чтения его содержимого.
Попытка
    НовоеЧтениеXML.ОткрытьФайл(Сайт);
Исключение
    Сообщить("Не удалось открыть файл XSD: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

// 3. Создадим построитель документа DOM по умолчанию.
НовыйПостроительDOM = Новый ПостроительDOM;

// 4. Прочитаем файл XSD в документ DOM.
// Это позволяет получить древовидное представление структуры XSD в памяти.
Попытка
    НовыйДокументDOM = НовыйПостроительDOM.Прочитать(НовоеЧтениеXML);
Исключение
    Сообщить("Ошибка при чтении XSD в DOM: " + ОписаниеОшибки());
    НовоеЧтениеXML.Закрыть();
    Возврат;
КонецПопытки;

// Обязательно закроем объект чтения XML после использования.
НовоеЧтениеXML.Закрыть();

// 5. Создадим построитель схемы XML по умолчанию.
НовыйПостроительСхемXML = Новый ПостроительСхемXML;

// 6. Получим схему XML из документа DOM.
// Этот шаг интерпретирует DOM-представление XSD в объект 1С: СхемаXML.
Попытка
    НоваяСхемаXML = НовыйПостроительСхемXML.СоздатьСхемуXML(НовыйДокументDOM);
Исключение
    Сообщить("Ошибка при создании СхемыXML из DOM: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

// 7. Создадим набор схем XML по умолчанию.
// Набор схем позволяет объединить несколько XSD-схем, если они взаимосвязаны.
НовыйНаборСхемXML = Новый НаборСхемXML;

// 8. Добавим нашу схему XML в набор схем XML.
НовыйНаборСхемXML.Добавить(НоваяСхемаXML);

// 9. Создадим ФабрикуXDTO на основе набора схем XML.
// Теперь ФабрикаXDTO готова к работе и знает все типы, определенные в XSD.
НоваяФабрикаXDTO = Новый ФабрикаXDTO(НовыйНаборСхемXML);

// Для отладки и понимания структуры мы можем пройтись по пакетам и корневым свойствам:
Для Каждого Пакет Из НоваяФабрикаXDTO.Пакеты Цикл
    Сообщить("Пакет: " + Пакет.Имя);
    Для Каждого ТипXDTOСхемы Из Пакет.ВсеТипы Цикл
        // Сообщить("  Тип: " + ТипXDTOСхемы.Имя);
    КонецЦикла;
    Для Каждого КорневоеСвойство Из Пакет.КорневыеСвойства Цикл
        Сообщить("  Корневое свойство (элемент): " + КорневоеСвойство.Имя + " (Тип: " + КорневоеСвойство.Тип.Имя + ")");
    КонецЦикла;
КонецЦикла;

Этот код позволяет динамически загрузить XSD-схему и создать работоспособную ФабрикуXDTO. Объект НоваяФабрикаXDTO теперь содержит всю информацию о типах данных, элементах и атрибутах, описанных в XSD, и готов к использованию для создания объектов XDTO.

3. Определение структуры XML из XSD-схемы без примера файла

Одна из самых сложных частей задачи — понять, как должен выглядеть итоговый XML-файл, если у вас есть только XSD-схема, но нет примера файла XML. Схема — это лишь описание возможных структур, а не конкретный пример. Тем не менее, мы можем "прочитать" ее, чтобы определить ожидаемый формат.

Поиск корневого элемента

Каждый XML-документ имеет единственный корневой элемент. В XSD-схеме корневой элемент обычно определяется с помощью элемента <xs:element> на верхнем уровне, который не является частью сложного типа (complexType) другого элемента. Он часто имеет атрибут name, который соответствует имени корневого тега в XML-файле.

Например, в схеме Yandex Market Language (YML), корневым элементом является yml_catalog — для формирования такого файла есть готовая обработка выгрузки товаров на Яндекс Маркет в формате YML. Вы можете найти его в XSD-файле как:

<xs:element name="yml_catalog" type="yml_catalogType"/>

В этом случае yml_catalog — это имя корневого элемента, а yml_catalogType — сложный тип, который описывает его содержимое.

Анализ сложных типов (complexType)

После определения корневого элемента необходимо изучить его complexType (сложный тип), который описывает содержимое этого элемента. Внутри complexType вы найдете:

Внутри этих конструкций вы увидите дочерние элементы (<xs:element>) и их атрибуты (<xs:attribute>). Обращайте внимание на следующие атрибуты:

Например, если вы видите:


<xs:complexType name="yml_catalogType">
    <xs:sequence>
        <xs:element name="shop" type="shopType" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="date" type="xs:dateTime" use="required"/>
</xs:complexType>

Это означает, что корневой элемент yml_catalog должен содержать один или несколько элементов shop (потому что maxOccurs="unbounded") и обязательный атрибут date типа дата/время. Далее вам нужно будет изучить shopType.

Разбор anyType

Если в схеме вы видите, что тип элемента определен как xs:anyType, это означает, что в этот элемент могут быть вложены вообще любые допустимые XML-элементы. Это существенно повышает вариативность и неопределенность. В 1С это может потребовать:

Использование утилит для просмотра XSD

Для более наглядного анализа XSD-схемы без примера XML-файла существуют сторонние инструменты и онлайн-сервисы, которые могут графически отображать структуру XSD (например, "XML Schema Viewer"). Они помогают визуализировать иерархию элементов, их типы и обязательность, делая схему гораздо более понятной.

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

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

Теперь, когда у нас есть ФабрикаXDTO и мы понимаем структуру схемы, мы можем приступить к созданию и заполнению объектов, которые затем будут преобразованы в XML. В 1С для этого используются объекты типа ОбъектXDTO.

Получение типа XDTO

Чтобы создать ОбъектXDTO, нам нужно получить соответствующий тип из нашей ФабрикиXDTO. Типы организованы по пакетам (соответствующим целевым пространствам имен в XSD).

Если вы знаете имя пакета и имя типа (элемента), вы можете получить его так:


// Предположим, корневой элемент нашей схемы называется "yml_catalog"
// и находится в пакете с именем "http://market.yandex.ru" (или другим, указанным в схеме).
ИмяПакета = "http://market.yandex.ru"; // Или другое имя пакета из XSD
ИмяКорневогоТипа = "yml_catalogType"; // Или другое имя типа корневого элемента

// Получаем тип из ФабрикиXDTO
ТипКорневогоОбъектаXDTO = НоваяФабрикаXDTO.Пакеты[ИмяПакета].ПолучитьТип(ИмяКорневогоТипа);

Если ТипКорневогоОбъектаXDTO = Неопределено Тогда
    Сообщить("Не удалось найти тип '" + ИмяКорневогоТипа + "' в пакете '" + ИмяПакета + "'. Проверьте XSD-схему и имена.");
    Возврат;
КонецЕсли;

Если вы не уверены в имени пакета или типа, вы можете использовать циклы, как показано в примере создания ФабрикиXDTO, чтобы вывести все доступные пакеты и типы и найти нужный.

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

После получения нужного типа мы можем создать экземпляр ОбъектаXDTO с помощью метода Создать ФабрикиXDTO:


// Создаем корневой ОбъектXDTO
КорневойОбъектXDTO = НоваяФабрикаXDTO.Создать(ТипКорневогоОбъектаXDTO);

Заполнение ОбъектаXDTO

Заполнение ОбъектаXDTO происходит путем обращения к его свойствам, имена которых соответствуют именам дочерних элементов и атрибутов, определенных в XSD-схеме.

Рассмотрим гипотетический пример, основанный на структуре YML, где yml_catalog содержит shop, а shop содержит name и список offers: для автоматического создания таких файлов есть обработка формирования XML и YML по требованиям внешних площадок.


// --- 1. Заполняем корневой объект yml_catalog ---
// Установим атрибут 'date' для корневого элемента.
// В XSD это <xs:attribute name="date" type="xs:dateTime" use="required"/>
КорневойОбъектXDTO.Дата = ТекущаяДата(); // Атрибуты в 1С часто доступны как свойства с тем же именем

// --- 2. Создаем и заполняем элемент 'shop' ---
// Предположим, что тип для 'shop' называется "shopType" в том же пакете
ТипShopXDTO = НоваяФабрикаXDTO.Пакеты[ИмяПакета].ПолучитьТип("shopType");
Если ТипShopXDTO = Неопределено Тогда
    Сообщить("Не удалось найти тип 'shopType'.");
    Возврат;
КонецЕсли;

ОбъектShopXDTO = НоваяФабрикаXDTO.Создать(ТипShopXDTO);

// Заполняем простые свойства элемента 'shop'
ОбъектShopXDTO.Название = "Мой интернет-магазин"; // Соответствует <xs:element name="name" type="xs:string"/>
ОбъектShopXDTO.Компания = "ООО 'Пример'";
ОбъектShopXDTO.URL = "https://www.example.com";

// Добавляем заполненный ОбъектShopXDTO в коллекцию 'shop' корневого объекта.
// В нашем XSD-примере shop имел maxOccurs="unbounded", поэтому КорневойОбъектXDTO.Shop
// будет коллекцией.
// Важно: Имя свойства в 1С (например, КорневойОбъектXDTO.Shop) будет соответствовать
// имени элемента из схемы (xs:element name="shop").
КорневойОбъектXDTO.shop.Добавить(ОбъектShopXDTO);

// --- 3. Создаем и заполняем список 'offers' внутри 'shop' ---
// Предположим, что тип для 'offer' называется "offerType"
ТипOfferXDTO = НоваяФабрикаXDTO.Пакеты[ИмяПакета].ПолучитьТип("offerType");
Если ТипOfferXDTO = Неопределено Тогда
    Сообщить("Не удалось найти тип 'offerType'.");
    Возврат;
КонецЕсли;

// Добавляем первый товар (offer)
ОбъектOfferXDTO1 = НоваяФабрикаXDTO.Создать(ТипOfferXDTO);
ОбъектOfferXDTO1.Id = "12345"; // Атрибут id элемента offer
ОбъектOfferXDTO1.Доступен = Истина; // Атрибут available элемента offer
ОбъектOfferXDTO1.URL = "https://www.example.com/product/1";
ОбъектOfferXDTO1.Цена = 1000;
ОбъектOfferXDTO1.ВалютаId = "RUB";
ОбъектOfferXDTO1.Название = "Пример товара 1";
ОбъектOfferXDTO1.Описание = "Подробное описание первого товара.";
ОбъектShopXDTO.offers.Добавить(ОбъектOfferXDTO1); // 'offers' - это коллекция внутри 'shop'

// Добавляем второй товар (offer)
ОбъектOfferXDTO2 = НоваяФабрикаXDTO.Создать(ТипOfferXDTO);
ОбъектOfferXDTO2.Id = "67890";
ОбъектOfferXDTO2.Доступен = Ложь;
ОбъектOfferXDTO2.URL = "https://www.example.com/product/2";
ОбъектOfferXDTO2.Цена = 2500;
ОбъектOfferXDTO2.ВалютаId = "RUB";
ОбъектOfferXDTO2.Название = "Пример товара 2";
ОбъектOfferXDTO2.Описание = "Подробное описание второго товара.";
ОбъектShopXDTO.offers.Добавить(ОбъектOfferXDTO2);

Важно: При заполнении свойств ОбъектаXDTO имена свойств должны строго соответствовать именам элементов или атрибутов, определенным в XSD-схеме (с учетом регистра!). Если в схеме элемент называется "Price", то в 1С это будет ОбъектXDTO.Price, а не ОбъектXDTO.Цена.

5. Запись XML-файла

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


// Путь к файлу, куда будет записан XML
ПутьКФайлуXML = "C:\МоиВыгрузки\output.xml";

// Создаем объект ЗаписьXML
ЗаписьXML = Новый ЗаписьXML;

Попытка
    // Открываем файл для записи. Указываем кодировку UTF-8 (чаще всего используется).
    // Стандартные отступы делают XML более читаемым.
    ЗаписьXML.ОткрытьФайл(ПутьКФайлуXML, "UTF-8", СтандартныеОтступыXML.Истина);

    // Записываем корневой ОбъектXDTO в файл.
    // ФабрикаXDTO автоматически определяет правила сериализации на основе XSD.
    НоваяФабрикаXDTO.ЗаписатьXDTO(ЗаписьXML, КорневойОбъектXDTO);

    // Закрываем файл. Это ОБЯЗАТЕЛЬНО для сохранения данных.
    ЗаписьXML.Закрыть();

    Сообщить("XML-файл успешно выгружен по пути: " + ПутьКФайлуXML);

Исключение
    Сообщить("Ошибка при записи XML-файла: " + ОписаниеОшибки());
    Если ЗаписьXML.Открыт() Тогда
        ЗаписьXML.Закрыть();
    КонецЕсли;
КонецПопытки;

После выполнения этого кода на указанном пути будет создан XML-файл с данными, сформированными согласно XSD-схеме и заполненными из наших ОбъектовXDTO.

6. Дополнительные рекомендации

Пространства имен (Namespaces)

Если ваша XSD-схема использует пространства имен (targetNamespace), убедитесь, что они правильно обрабатываются. При импорте схемы в 1С или при создании ФабрикиXDTO, 1С обычно автоматически учитывает пространства имен. При обращении к типам через ФабрикаXDTO.Пакеты[ИмяПакета], ИмяПакета часто соответствует целевому пространству имен (targetNamespace), указанному в XSD.

Валидация XML

В 1С нет встроенных средств для валидации сгенерированного XML-файла по XSD-схеме после его создания. Для полной уверенности в корректности сгенерированного файла и его соответствии XSD-схеме рекомендуется использовать внешние инструменты валидации XML. Существуют как онлайн-валидаторы, так и десктопные приложения (например, XMLSpy, Oxygen XML Editor, или бесплатные утилиты типа xmllint), которые могут точно указать на любые несоответствия схеме. При необходимости выполнять такую проверку непосредственно в базе 1С можно использовать обработку для валидации XML-файлов на соответствие XSD-схеме.

Отладка

При возникновении ошибок при записи XML или при его некорректном формировании, используйте отладчик 1С. Вы можете поставить точку останова перед вызовом НоваяФабрикаXDTO.ЗаписатьXDTO() и просмотреть структуру и значения КорневойОбъектXDTO. Это позволит убедиться, что все свойства заполнены правильно, коллекции содержат ожидаемое количество элементов, и нет пропущенных обязательных полей.

Особое внимание уделяйте типам данных. Например, если в XSD ожидается xs:dateTime, а вы присваиваете строку, это может вызвать ошибку валидации или некорректную запись.

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

← На главную