Выгрузка данных в формате XML — это стандартная задача при организации обмена данными между 1С и внешними информационными системами (например, государственными порталами, банковскими сервисами или веб-сайтами). Часто получатель требует строгого соблюдения структуры, где один и тот же элемент должен содержать и атрибуты, и вложенные дочерние узлы с данными. В этой статье мы подробно разберем, как реализовать такую структуру программно, проанализируем типичные ошибки начинающих разработчиков и рассмотрим альтернативные подходы для решения сложных задач.
Для начала проанализируем формат, который нам необходимо получить:
<ROW NAME="DOCDATE" TAB="0" LINE="0"> <VALUE>04.12.2018 00:00:00</VALUE> </ROW>
Здесь мы видим сложный элемент ROW, который имеет:
NAME, TAB и LINE.VALUE, который, в свою очередь, содержит текстовое значение (дату).Основная сложность у разработчиков часто возникает в последовательности вызова методов объекта ЗаписьXML. Рассмотрим, как правильно выстроить алгоритм работы.
Самый эффективный и быстрый способ формирования XML-файлов в 1С — это использование низкоуровневого объекта ЗаписьXML. Он работает в потоковом режиме, что позволяет выгружать файлы практически неограниченного объема с минимальным потреблением оперативной памяти.
Разберем по шагам правильную последовательность действий для создания нашего элемента:
// 1. Создаем объект записи и открываем файл
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\Exports\Document.xml", "UTF-8");
// 2. Записываем начало корневого элемента (например, DOCUMENT)
ЗаписьXML.ЗаписатьНачалоЭлемента("DOCUMENT");
// 3. Создаем элемент ROW
ЗаписьXML.ЗаписатьНачалоЭлемента("ROW");
// 4. СРАЗУ после начала элемента записываем его атрибуты
// Важно: атрибуты можно записывать только до того, как открыт вложенный элемент или записан текст
ЗаписьXML.ЗаписатьАтрибут("NAME", "DOCDATE");
ЗаписьXML.ЗаписатьАтрибут("TAB", "0");
ЗаписьXML.ЗаписатьАтрибут("LINE", "0");
// 5. Создаем вложенный элемент VALUE
ЗаписьXML.ЗаписатьНачалоЭлемента("VALUE");
// 6. Записываем текстовое содержимое вложенного элемента
// Рекомендуется использовать XMLСтрока() для правильного форматирования дат и чисел
ТекстДаты = XMLСтрока(ТекущаяДата());
ЗаписьXML.ЗаписатьТекст(ТекстДаты);
// 7. Закрываем элемент VALUE
ЗаписьXML.ЗаписатьКонецЭлемента();
// 8. Закрываем элемент ROW
ЗаписьXML.ЗаписатьКонецЭлемента();
// 9. Закрываем корневой элемент и завершаем запись
ЗаписьXML.ЗаписатьКонецЭлемента();
ЗаписьXML.Закрыть();
Важный нюанс: Обратите внимание на порядок вызовов. Метод ЗаписатьАтрибут должен следовать строго после ЗаписатьНачалоЭлемента того узла, к которому он относится. Если вы сначала вызовете ЗаписатьНачалоЭлемента("VALUE"), а потом попытаетесь добавить атрибут к ROW, система выдаст ошибку, так как контекст записи уже перешел к вложенному узлу.
Если вы просто выполните код выше, 1С сформирует файл в одну длинную строку. Это допустимо для программной обработки, но крайне неудобно для отладки человеком. Чтобы файл выглядел структурировано (с отступами и переносами строк), необходимо использовать ПараметрыЗаписиXML.
Проанализируем пример настройки параметров:
ПараметрыЗаписи = Новый ПараметрыЗаписиXML("UTF-8", "1.0", Истина, Истина, Символы.Таб);
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\Exports\FormattedDocument.xml", ПараметрыЗаписи);
// Далее идет стандартный код записи...
Здесь параметры означают следующее:
"UTF-8" — кодировка файла."1.0" — версия XML.Истина — записывать заголовок XML (XML declaration).Истина — использовать отступы для визуализации иерархии.Символы.Таб — в качестве символа отступа использовать табуляцию (можно заменить на пробелы).Рассмотрим ситуацию, когда данных много и они записываются в цикле. Часто разработчики забывают вовремя закрывать элементы, что приводит к нарушению структуры XML (невалидности файла).
Ошибка 1: Неправильное преобразование типов. Использование функции Строка() для дат и чисел может привести к непредсказуемым результатам, так как формат зависит от региональных настроек сервера или пользователя. Выясним причину: в одной системе дата выгрузится как "04.12.2018", а в другой как "04/12/18". Для XML-стандартов всегда используйте XMLСтрока(Значение) — это гарантирует универсальный формат ISO.
Ошибка 2: Спецсимволы в данных. Если в поле "VALUE" попадут символы типа амперсанда (&) или угловых скобок (<), ЗаписьXML.ЗаписатьТекст() автоматически их экранирует (превратит в & и <). Это правильное поведение. Однако, если вы попытаетесь собрать XML "вручную" простой конкатенацией строк, ваш файл может "развалиться" при чтении.
В некоторых случаях использование ЗаписьXML может быть избыточно сложным из-за необходимости вручную следить за каждым тегом. Рассмотрим альтернативы.
1. Механизм XDTO (XML Data Transfer Objects)
Если у вас есть готовая схема XSD (описание формата), лучше всего загрузить её в конфигурацию как "Пакет XDTO". В этом случае вы работаете не с "тегами", а с объектами 1С. Вы создаете объект типа "ROW", заполняете его свойства (NAME, TAB, LINE), создаете вложенный объект "VALUE", и затем одной командой СериализаторXDTO.ЗаписатьXML() выгружаете всё дерево. Это исключает ошибки в названиях тегов и атрибутов.
2. Объектная модель документа (DOM)
Если вам нужно создать структуру документа, а потом "вернуться назад" и что-то изменить (например, вписать в первый тег общую сумму, которую вы узнали только в конце цикла), используйте ДокументDOM. Этот метод строит дерево в памяти. Однако помните: для очень больших файлов (десятки и сотни мегабайт) DOM использовать нельзя, так как он может переполнить оперативную память сервера.
Мы рассмотрели основной и наиболее надежный способ формирования XML с атрибутами в 1С. Главный секрет успеха здесь заключается в строгом соблюдении последовательности: открыли узел — сразу записали атрибуты — открыли вложенные узлы — закрыли все узлы в обратном порядке. Использование ПараметровЗаписиXML и функции XMLСтрока() сделает ваши файлы профессиональными и совместимыми с любыми внешними системами.