При интеграции 1С с внешними системами или поставщиками часто возникает задача выгрузки данных в формате XML. На первый взгляд задача кажется тривиальной, но при детальном рассмотрении возникает вопрос выбора инструмента: использовать ли строгие XDTO-схемы, прибегнуть к последовательной записи или вовсе ограничиться текстовыми шаблонами? В этой статье мы подробно разберем все доступные механизмы, проанализируем их сильные и слабые стороны и научимся выбирать оптимальный путь для каждой конкретной задачи.
Рассмотрим самый простой и быстрый в реализации способ — формирование XML как обычной текстовой строки. Этот метод часто выбирают для разовых задач или очень простых структур, где количество полей минимально.
Суть метода заключается в создании макета (строки), где на месте будущих значений стоят маркеры, которые затем заменяются через функцию СтрЗаменить. Посмотрим на пример реализации:
ТекстШаблона = "<Root>
| <Vendor>[ИмяПоставщика]</Vendor>
| <Date>[ДатаВыгрузки]</Date>
|</Root>";
ТекстРезультат = СтрЗаменить(ТекстШаблона, "[ИмяПоставщика]", Поставщик.Наименование);
ТекстРезультат = СтрЗаменить(ТекстРезультат, "[ДатаВыгрузки]", Формат(ТекущаяДата(), "ДФ=yyyy-MM-dd"));
Важное предостережение: Проанализируем ситуацию, когда в наименовании поставщика встречается символ амперсанда (&) или кавычки. В этом случае ваш XML станет невалидным, так как текстовый метод не умеет автоматически экранировать спецсимволы. Если вы используете этот подход, обязательно обрабатывайте строки функцией НайтиНедопустимыеСимволыXML или самостоятельно заменяйте & на &, < на < и так далее. Из-за этих рисков данный метод не рекомендуется для серьезных интеграций.
Выясним, почему профессиональные разработчики предпочитают объект ЗаписьXML. Это "золотая середина" между сложностью и надежностью. Данный механизм записывает данные потоком, что позволяет формировать файлы огромного объема (гигабайты) без перегрузки оперативной памяти.
Разберем по шагам процесс создания файла:
ЗаписьXML и открываем файл.
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл("C:\temp\export.xml", "UTF-8");
Запись.ЗаписатьОбъявлениеXML();
Запись.ЗаписатьНачалоЭлемента("Catalog");
// Пример записи в цикле
Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
Запись.ЗаписатьНачалоЭлемента("Item");
Запись.ЗаписатьАтрибут("Code", Выборка.Код);
Запись.ЗаписатьНачалоЭлемента("Name");
Запись.ЗаписатьТекст(Выборка.Наименование); // Спецсимволы экранируются автоматически!
Запись.ЗаписатьКонецЭлемента(); // Name
Запись.ЗаписатьКонецЭлемента(); // Item
КонецЦикла;
Запись.ЗаписатьКонецЭлемента(); // Catalog
Запись.Закрыть();
Этот метод гарантирует корректность структуры файла и отсутствие проблем со спецсимволами. Однако при очень сложной вложенности код может стать трудночитаемым ("лапша" из бесконечных ЗаписатьНачалоЭлемента).
Проанализируем самый мощный инструмент — XDTO. Рассмотрим ситуацию, когда поставщик предоставил вам готовую схему XSD. В этом случае XDTO становится незаменимым, так как позволяет работать с XML как с обычными объектами 1С (через точку).
Преимущества XDTO:
Проверить(), и система скажет, соответствует ли ваш файл правилам (все ли обязательные поля заполнены, верные ли типы данных).ЗаполнитьЗначенияСвойств для быстрой перекачки данных из структуры или запроса в объект XDTO.Посмотрим на пример работы, если у нас уже есть схема в конфигурации:
ТипОбъекта = ФабрикаXDTO.Тип("http://www.my-vendor.com", "Order");
НовыйЗаказXML = ФабрикаXDTO.Создать(ТипОбъекта);
НовыйЗаказXML.Number = "001";
НовыйЗаказXML.Date = ТекущаяДата();
// Используем ЗаполнитьЗначенияСвойств для упрощения
СтруктураДанных = Новый Структура("Client, Total", "ООО Ромашка", 1500);
ЗаполнитьЗначенияСвойств(НовыйЗаказXML, СтруктураДанных);
// Запись объекта в файл
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл("C:\temp\order.xml");
ФабрикаXDTO.Записать(Запись, НовыйЗаказXML);
Запись.Закрыть();
Если схемы нет, её можно сгенерировать программно из образца XML или создать в дереве конфигурации вручную. Несмотря на кажущийся "оверхед", для сложных обменов этот метод экономит массу времени на поддержке кода.
Малоизвестный, но крайне эффективный способ — использование системного СериализатораXDTO. Он позволяет выгрузить объект 1С целиком в XML одной строчкой кода. Это полезно, если принимающая сторона — тоже 1С, или если структура объекта 1С вас полностью устраивает.
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл("C:\temp\ref.xml");
СериализаторXDTO.ЗаписатьXML(Запись, СсылкаНаОбъект); // Записывает весь объект со всеми реквизитами
Запись.Закрыть();
Посмотрим на метод DOM (Document Object Model). В отличие от ЗаписьXML, который пишет данные сразу "в трубу", DOM строит все дерево документа в оперативной памяти.
Рассмотрим ситуацию, когда это оправдано: вам нужно создать сложную структуру, где порядок узлов зависит от условий, которые выясняются в конце процесса, или нужно "прыгать" по дереву, добавляя атрибуты в уже созданные ранее узлы.
Важно: Не используйте DOM для файлов объемом более 10-20 Мб, так как потребление памяти будет в несколько раз превышать размер самого файла.
ДокументDOM = Новый ДокументDOM;
КорневойУзел = ДокументDOM.СоздатьЭлемент("Root");
ДокументDOM.ДобавитьПодчиненный(КорневойУзел);
НовыйУзел = ДокументDOM.СоздатьЭлемент("SubNode");
НовыйУзел.УстановитьАтрибут("Status", "Active");
КорневойУзел.ДобавитьПодчиненный(НовыйУзел);
// Запись DOM в файл
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл("C:\temp\dom.xml");
ЗаписьDOM = Новый ЗаписьDOM;
ЗаписьDOM.Записать(ДокументDOM, Запись);
Запись.Закрыть();
Подводя итог нашему анализу, выделим стратегию выбора инструмента для записи XML:
XSD.Помните также о пространствах имен (Namespaces). При использовании ЗаписьXML не забывайте про метод ЗаписатьСоответствиеПространствИмен, чтобы префиксы (например, xmlns:xs) проставлялись корректно. Это критически важно для современных веб-сервисов.