Как выгрузить дату в XML в виде отдельного элемента, а не атрибута в 1С

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

При интеграции 1С со сторонними информационными системами разработчики часто сталкиваются с жесткими требованиями к структуре XML-документов. Распространенной задачей является вывод данных в виде отдельных вложенных элементов (тегов) вместо записи атрибутов внутри одного тега. Например, вместо компактного атрибута <VERSION CREATEDATE="14.12.2018"/> принимающая сторона может требовать развернутую структуру с отдельным подчиненным элементом: <CREATEDATE>04.12.2018</CREATEDATE>.

В этой статье мы подробно разберем, как решить данную задачу с помощью встроенного в платформу 1С:Предприятие объекта ЗаписьXML, а также рассмотрим более надежные и современные альтернативы: встроенную XML-сериализацию, технологию XDTO и объектную модель DOM.

Способ 1. Последовательная запись с использованием ЗаписатьТекст

Основная ошибка при решении этой задачи заключается в использовании метода ЗаписатьАтрибут(). Этот метод добавляет свойство внутрь открытого тега. Чтобы получить полноценный элемент со значением внутри, нам необходимо открыть элемент, записать в него строковое значение и закрыть элемент. Для записи текстового контента между тегами используется метод ЗаписатьТекст().

Проанализируем простейший пример, который решает поставленную задачу:


// Инициализируем объект записи
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\temp\export.xml", "UTF-8");

// Открываем корневой или родительский элемент
ЗаписьXML.ЗаписатьНачалоЭлемента("VERSION");

// Открываем подчиненный элемент для даты
ЗаписьXML.ЗаписатьНачалоЭлемента("CREATEDATE");

// Записываем строковое значение даты в нужном формате
ЗаписьXML.ЗаписатьТекст(Формат(ТекущаяДата(), "ДФ=dd.MM.yyyy"));

// Закрываем подчиненный элемент
ЗаписьXML.ЗаписатьКонецЭлемента(); // Закроет </CREATEDATE>

// Закрываем родительский элемент
ЗаписьXML.ЗаписатьКонецЭлемента(); // Закроет </VERSION>

// Завершаем работу с файлом
ЗаписьXML.Закрыть();

В результате выполнения этого кода мы получим корректную структуру XML:


<VERSION>
    <CREATEDATE>14.12.2018</CREATEDATE>
</VERSION>

Способ 2. Стандартизация формата даты и встроенная функция XMLСтрока

Использование функции Формат() с явным указанием маски ДФ=dd.MM.yyyy оправдано только в том случае, если принимающая программа не умеет работать со стандартными форматами XML. В международной практике обмена данными общепринятым стандартом для дат является формат ISO 8601 (например, YYYY-MM-DD или YYYY-MM-DDThh:mm:ss).

В платформе 1С реализован глобальный метод XMLСтрока(). Он автоматически преобразует переданное значение (дату, число, булево) в канонический строковый вид, соответствующий спецификации W3C XML Schema. Это позволяет избежать ручного написания шаблонов форматирования и гарантирует корректное чтение данных любыми внешними парсерами.

Выясним, как изменится наш код при использовании встроенной сериализации:


ЗаписьXML.ЗаписатьНачалоЭлемента("CREATEDATE");
// Функция автоматически преобразует дату в стандартный формат (например, 2018-12-14T00:00:00)
ЗаписьXML.ЗаписатьТекст(XMLСтрока(ТекущаяДата()));
ЗаписьXML.ЗаписатьКонецЭлемента();

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


ЗаписьXML.ЗаписатьНачалоЭлемента("CREATEDATE");
ЗаписатьXML(ЗаписьXML, НачалоДня(ТекущаяДата())); 
ЗаписьXML.ЗаписатьКонецЭлемента();

Способ 3. Использование объектной модели DOM (Document Object Model)

При ручном вызове методов ЗаписатьНачалоЭлемента() и ЗаписатьКонецЭлемента() в больших файлах легко допустить ошибку в иерархии тегов (например, забыть закрыть один из элементов). Чтобы абстрагироваться от последовательной записи и работать с XML-документом как с деревом объектов в оперативной памяти, рассмотрим использование модели DOM.

Этот подход позволяет сначала полностью выстроить логическую структуру документа, связать элементы друг с другом и лишь затем выгрузить результат в файл:


// Создаем основу DOM-документа
ДокументDOM = Новый ДокументDOM;

// Создаем элементы документа
ЭлементVersion = ДокументDOM.СоздатьЭлемент("VERSION");
ЭлементCreateDate = ДокументDOM.СоздатьЭлемент("CREATEDATE");

// Наполняем элемент даты текстовым содержимым
ЭлементCreateDate.ТекстовоеСодержимое = XMLСтрока(ТекущаяДата());

// Выстраиваем иерархию (вкладываем элементы)
ЭлементVersion.ДобавитьДочерний(ЭлементCreateDate);
ДокументDOM.ДобавитьДочерний(ЭлементVersion);

// Записываем готовый документ в файл через ЗаписатьDOM
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\temp\export_dom.xml", "UTF-8");

ЗаписатьDOM = Новый ЗаписатьDOM;
ЗаписатьDOM.Записать(ДокументDOM, ЗаписьXML);

ЗаписьXML.Закрыть();

Способ 4. Использование технологии XDTO (XML Data Transfer Objects)

Наиболее современным, надежным и гибким способом работы с XML в 1С является использование механизма XDTO. Если у вас есть готовая схема XML (файл .xsd), предоставленная интегратором, вы можете импортировать её в конфигурацию в качестве Пакета XDTO.

Использование XDTO дает программисту следующие важные преимущества:

  1. Строгая типизация: Платформа контролирует типы данных при заполнении свойств объекта.
  2. Автоматическое форматирование: Если в схеме XSD свойство имеет тип xs:date, система автоматически обрежет время и запишет дату в стандартном формате YYYY-MM-DD.
  3. Объектная работа: Вы заполняете свойства объекта так же просто, как работаете со Структурой в 1С, а генерацию тегов платформа берет на себя.

Рассмотрим пример создания и выгрузки объекта данных через фабрику XDTO:


// Предположим, у нас в конфигурации определен пакет XDTO с типом "VersionType"
// Получаем тип из фабрики XDTO
ТипXDTO = ФабрикаXDTO.Тип("http://www.your-integration-schema.ru", "VersionType");

// Создаем экземпляр объекта XDTO по выбранному типу
ОбъектVersion = ФабрикаXDTO.Создать(ТипXDTO);

// Заполняем дату (платформа сама преобразует дату 1С в формат XML при записи)
ОбъектVersion.CREATEDATE = ТекущаяДата(); 

// Записываем готовый объект в XML
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\temp\export_xdto.xml", "UTF-8");

ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, ОбъектVersion);

ЗаписьXML.Закрыть();

Использование фабрики XDTO полностью избавляет разработчика от необходимости вручную прописывать теги и следить за открытием/закрытием узлов структуры, сводя к минимуму вероятность возникновения синтаксических ошибок в результирующем файле.

← На главную