Как правильно записывать комментарии и обрабатывать пустые элементы при экспорте данных в XML в 1С?

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

При интеграции 1С с внешними информационными системами (будь то государственные порталы, личные кабинеты контрагентов, системы маркировки «Честный Знак» или веб-сервисы) разработчики регулярно сталкиваются с необходимостью формирования файлов в формате XML. На первый взгляд, задача кажется тривиальной, однако при детальной реализации возникает множество нюансов: от корректной вставки служебных комментариев до обработки пустых значений и прохождения валидации по XSD-схемам.

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

Как правильно записывать комментарии в XML средствами 1С

Рассмотрим ситуацию, когда в готовом шаблоне XML-документа присутствуют элементы вида <!-- 1 -->. Попытка записать их как обычные элементы через метод ЗаписатьНачалоЭлемента(), например, вызвав Запись.ЗаписатьНачалоЭлемента("!-- 1 --"), является грубой ошибкой. Имена тегов в XML не могут начинаться с восклицательного знака или содержать дефисы в служебных позициях. Платформа 1С выдаст ошибку времени выполнения, либо на выходе получится некорректная разметка, которую не примет ни один парсер.

Для создания комментариев в структуре XML-документа на платформе 1С предусмотрено два стандартных и безопасных пути. Выясним особенности каждого из них.

Способ 1. Использование специализированного метода ЗаписатьКомментарий()

У объекта ЗаписьXML существует встроенный метод, предназначенный специально для вывода комментариев. Он автоматически обрамляет переданный текст в угловые скобки с восклицательным знаком и дефисами <!-- -->. Посмотрим на пример кода:


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

Запись.ЗаписатьОбъявлениеXML();
Запись.ЗаписатьНачалоЭлемента("Root");

// Записываем комментарий средствами платформы
Запись.ЗаписатьКомментарий("  1  ");

Запись.ЗаписатьКонецЭлемента(); // Root
Запись.Закрыть();

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

<!-- 1 -->

Способ 2. Использование метода ЗаписатьБезОбработки()

В некоторых случаях вам может потребоваться вставить сложную, жестко заданную статическую разметку или специфический блок комментариев, не полагаясь на автоматическое форматирование платформы. Для этого отлично подходит метод ЗаписатьБезОбработки(). Проанализируем следующий пример:


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

// Платформа запишет строку ровно в том виде, в котором мы ее передали
Запись.ЗаписатьБезОбработки("<!--  1  -->");

Запись.ЗаписатьКонецЭлемента();
Запись.Закрыть();

Важное предупреждение: Метод ЗаписатьБезОбработки() обходит стандартные механизмы валидации платформы 1С. Если вы допустите синтаксическую ошибку в передаваемой строке (например, забудете закрыть скобку или кавычку), результирующий XML-документ станет нечитаемым для принимающей стороны. Используйте этот метод осмотрительно.

Пропуск элементов vs Пустые значения (XSD-валидация в 1С)

Еще один частый вопрос разработчиков: нужно ли обязательно выгружать теги, для которых в базе 1С нет данных? Можно ли их просто пропустить или обязательно передавать пустыми? Решение этой дилеммы полностью зависит от требований схемы XML (XSD-файла), по которой принимающая сторона проверяет ваш файл.

Разберем по шагам, как ведут себя элементы в зависимости от параметров схемы:

  1. Атрибут minOccurs (минимальное число вхождений):

    Если в XSD-схеме для элемента указано свойство minOccurs="0", это означает, что элемент является необязательным. Если данных для него в 1С нет, мы можем полностью опустить запись этого тега. Приемник успешно обработает файл.

    Если же minOccurs="1" (или этот атрибут вовсе не указан, что по умолчанию означает обязательность), то тег обязан присутствовать в XML-документе. Просто пропустить его нельзя — это вызовет ошибку валидации на стороне приемника.

  2. Атрибут nillable="true" (в 1С соответствует свойству XDTO ВозможноПустое):

    Если элемент обязателен для присутствия, но пуст по значению (например, незаполненный реквизит «Дата рождения» или «Сумма»), простая запись вида <DateOfBirth></DateOfBirth> для строго типизированных полей вызовет ошибку парсинга. Для обхода этого ограничения в XSD-схемах используется признак "nillable".

    Если схема допускает пустоту (nillable="true"), в XML-файл необходимо передать специальный признак отсутствия значения:

    <DateOfBirth xsi:nil="true"/>

Чтобы избавить себя от гадания на тему «примет ли портал наш файл», мы можем организовать автоматическую проверку сформированного XML прямо в коде 1С перед отправкой. Для этого нам понадобится файл XSD-схемы. Разберем пример реализации такой проверки с помощью механизма фабрики XDTO:


ПутьКФайлуСхемы = "C:\schemas\FES_Format.xsd";
ПутьКВыгруженномуФайлу = "C:\temp\export.xml";

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

Почему ручная запись XML опасна и как спасает XDTO

В процессе разработки часто возникает соблазн написать выгрузку «по-быстрому» через последовательный вызов методов ЗаписатьНачалоЭлемента() и ЗаписатьКонецЭлемента(). Однако ручное формирование структуры таит в себе скрытые опасности, которые могут проявиться только в промышленной эксплуатации.

Проблема 1. Спецсимволы в текстовых полях

Если в наименовании контрагента, номенклатуры или в адресе содержатся символы, являющиеся служебными для разметки XML (например, &, <, >, ", '), прямая их запись в файл разрушит всю структуру. Документ перестанет открываться. При ручной записи необходимо обязательно экранировать данные с помощью функции платформы XMLСтрока():


// Опасный вариант (может сломать XML, если в наименовании есть символ "&")
Запись.ЗаписатьТекст(Выборка.НаименованиеКонтрагента);

// Безопасный вариант с автоматическим экранированием спецсимволов
Запись.ЗаписатьТекст(XMLСтрока(Выборка.НаименованиеКонтрагента));

Проблема 2. Строгий порядок следования элементов

Большинство официальных XSD-схем требуют, чтобы элементы внутри родительского тега шли в строго определенном порядке (в схеме это задается контейнером <xs:sequence>). Если вы при ручном кодинге случайно перепутаете строки и запишете, например, тег <ИНН> после тега <КПП>, хотя в схеме описан обратный порядок, принимающий шлюз отклонит ваш файл.

Использование объектной модели XDTO (XML Data Transfer Objects) полностью решает эту проблему. Вы наполняете свойства объекта 1С в любом удобном для вас порядке в коде, а платформа при сериализации в XML сама выстраивает элементы в строгом соответствии с требованиями импортированной схемы.

Специфика обмена данными: ФЭС (115-ФЗ) и маркировка «Честный Знак»

В современной практике 1С-разработчики чаще всего сталкиваются со сложными требованиями XML-форматов в двух сферах: передача сведений в Росфинмониторинг (ФЭС по 115-ФЗ) и интеграция с государственной информационной системой маркировки товаров (ГИС МТ «Честный Знак»). Разберем их специфику.

Формализованные электронные сообщения (ФЭС 115-ФЗ)

Форматы ФЭС содержат сотни обязательных реквизитов с жесткой иерархией. Пытаться собирать такой XML вручную через цепочки ЗаписатьНачалоЭлемента() крайне нерационально и трудоемко. При любом минимальном изменении законодательства вам придется переписывать сотни строк процедур выгрузки. Единственным верным решением здесь является импорт XSD-схемы Росфинмониторинга в конфигурацию в качестве XDTO-пакета и заполнение структуры через объекты XDTO.

Маркировка («Честный Знак»)

При передаче сведений о кодах маркировки (например, при вводе товаров в оборот или их списании в личном кабинете ГИС МТ) возникает специфическая проблема. Сами коды DataMatrix содержат в себе скрытые и непечатные спецсимволы, такие как разделитель групп GS1 (символ с кодом ASCII 29, известный как FNC1). Если записать такой код напрямую, XML-парсер на стороне Честного Знака выдаст синтаксическую ошибку.

Чтобы избежать искажения кодов маркировки и сбоев при импорте, стандарты обмена требуют оборачивать строки с кодами в специальные секции CDATA (Character Data), которые говорят парсеру, что внутри находится чистый текст, который не нужно пытаться интерпретировать как разметку.

Посмотрим, как реализовать запись тегов с секцией CDATA в 1С:


// Предположим, у нас есть код маркировки со спецсимволами
КодМаркировки = "01046000000000215gY&tYtr" + Символ(29) + "91EE06" + Символ(29) + "92yH";

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

Запись.ЗаписатьНачалоЭлемента("ki_code");

// Записываем значение в безопасную секцию CDATA
Запись.ЗаписатьСекциюCDATA(КодМаркировки);

Запись.ЗаписатьКонецЭлемента(); // ki_code

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

В результирующем XML-файле мы получим абсолютно корректную структуру, готовую к успешной загрузке в личный кабинет системы маркировки:

<ki_code><![CDATA[01046000000000215gY&tYtr91EE0692yH]]></ki_code>

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

← На главную