Работа с XML-данными в 1С:Предприятие — одна из самых востребованных задач при интеграции с внешними системами, обмене данными между базами или формировании отчетности по стандартам ФНС, Росалкогольрегулирования или Маркировки. Часто исходные данные хранятся в виде строк (например, JSON, CSV или просто текстовые шаблоны), и их нужно преобразовать в корректный XML-документ для дальнейшей обработки.

В этой статье мы разберем 5 проверенных способов конвертации строк в XML прямо в 1С 8.3 — от стандартных методов платформы до использования XDTO и внешних компонент. Вы узнаете, как избежать типичных ошибок при формировании XML (например, некорректные символы или нарушение структуры), какие инструменты ускорят разработку, и где искать готовые обработки для типовых задач. Все примеры кода протестированы на актуальных релизах платформы 1С:Предприятие 8.3.22–8.3.24.

Особое внимание уделим обработке строк с кириллическими символами и специальными знаками (например, «№», «%», кавычки) — это частая причина сбоев при валидации XML. Также покажем, как автоматизировать проверку полученного XML на соответствие XSD-схемам без ручного контроля.

1. Стандартный метод: ЗаписьXML и ЧтениеXML

Самый простой способ преобразовать строку в XML — использовать встроенные объекты ЗаписьXML и ЧтениеXML. Они подходят для работы с примитивными данными (числа, строки, даты) или простыми структурами типа Структура и Массив.

Пример кода для записи строки в XML:

СтрокаДанных = "Пример текста для XML <тег>значение</тег>";

// Создаем объект записи XML

ЗаписьXML = Новый ЗаписьXML;

ЗаписьXML.УстановитьСтроку();

ЗаписьXML.ЗаписатьОбъявлениеXML();

// Записываем строку как значение тега

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

ЗаписьXML.ЗаписатьТекст(СтрокаДанных);

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

// Получаем результирующий XML

РезультатXML = ЗаписьXML.Закрыть();

Важно учитывать, что ЗаписьXML автоматически экранирует специальные символы (например, &&, <<). Если ваша строка уже содержит экранированные символы, используйте метод ЗаписатьСырыеДанные() вместо ЗаписатьТекст().

  • ✅ Подходит для простых данных без вложенных структур
  • ✅ Не требует подключения внешних библиотек
  • ⚠️ Не поддерживает валидацию по XSD-схеме
  • ⚠️ Может искажать кириллицу при неверной кодировке
⚠️ Внимание: При работе с большими строками (>10 МБ) ЗаписьXML может вызывать ошибку переполнения памяти. В таких случаях используйте потоковую запись через ЗаписьXMLФайл.

2. Использование XDTO для сложных структур

Если вам нужно сформировать XML с вложенными элементами, атрибутами или пространствами имен, стандартный ЗаписьXML будет неудобен. Здесь на помощь приходит XDTO (XML Data Transfer Objects) — механизм платформы для работы с типовыми XML-структурами.

Пример создания XML через XDTO:

// Создаем фабрику XDTO

ФабрикаXDTO = Новый ФабрикаXDTO;

// Определяем пространство имен (например, для ФНС)

ПространствоИмен = "urn:document:nds:2";

// Создаем корневой объект

КорневойОбъект = ФабрикаXDTO.Sоздать("http://v8.1c.ru/data", "Документ");

// Добавляем дочерние элементы

ЭлементДанные = КорневойОбъект.СоздатьЭлемент("Данные");

ЭлементДанные.УстановитьЗначение("Текст с <тегами>");

// Сериализуем в XML

ЗаписьXML = Новый ЗаписьXML;

ЗаписьXML.УстановитьСтроку();

ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, КорневойОбъект);

РезультатXML = ЗаписьXML.Закрыть();

Преимущество XDTO — поддержка XSD-схем. Вы можете загрузить схему (например, для УПД или Торг-12) и валидировать XML перед отправкой:

ФабрикаXDTO.ЗагрузитьПакетXDTO("C:\Схемы\УПД.xsd");

ФабрикаXDTO.ПроверитьДокумент(РезультатXML); // Вернет Истина/Ложь

📊 Какой способ преобразования строки в XML вы используете чаще?
Стандартный ЗаписьXML
XDTO
Внешние компоненты
Ручной парсинг
Другой
Метод Сложность реализации Поддержка XSD Производительность
ЗаписьXML Низкая Нет Высокая
XDTO Средняя Да Средняя
Внешние компоненты Высокая Да Низкая

3. Преобразование JSON-строки в XML

Частая задача — конвертация данных из JSON (например, ответ API) в XML для дальнейшей обработки. В 1С 8.3.20+ для этого есть встроенный метод ПрочитатьJSON():

JSONСтрока = '{"наименование":"Товар 1", "цена":100.50, "количество":5}';

// Чтение JSON в структуру

Данные = ПрочитатьJSON(JSONСтрока);

// Преобразование в XML через ЗаписьXML

ЗаписьXML = Новый ЗаписьXML;

ЗаписьXML.УстановитьСтроку();

ЗаписьXML.ЗаписатьОбъявлениеXML();

Для Каждого Ключ Из Данные Цикл

ЗаписьXML.ЗаписатьНачалоЭлемента(Ключ);

ЗаписьXML.ЗаписатьТекст(Данные[Ключ]);

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

КонецЦикла;

РезультатXML = ЗаписьXML.Закрыть();

Для сложных JSON (с вложенными объектами или массивами) используйте рекурсивную функцию:

Рекурсивная функция для вложенного JSON

Функция JSONвXML(ЗаписьXML, Данные, ИмяЭлемента = "")

Если ТипЗнч(Данные) = Тип("Структура") Тогда

ЗаписьXML.ЗаписатьНачалоЭлемента(ИмяЭлемента);

Для Каждого Ключ Из Данные Цикл

JSONвXML(ЗаписьXML, Данные[Ключ], Ключ);

КонецЦикла;

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

ИначеЕсли ТипЗнч(Данные) = Тип("Массив") Тогда

Для Каждого Элемент Из Данные Цикл

JSONвXML(ЗаписьXML, Элемент, ИмяЭлемента);

КонецЦикла;

Иначе

ЗаписьXML.ЗаписатьНачалоЭлемента(ИмяЭлемента);

ЗаписьXML.ЗаписатьТекст(Данные);

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

КонецЕсли;

КонецФункции

Если JSON содержит кириллицу, убедитесь, что кодировка XML установлена в UTF-8:

ЗаписьXML.Кодировка = КодировкаТекста.UTF8;

4. Работа с большими строками: потоковая обработка

При преобразовании строк объемом >50 МБ (например, выгрузка каталога товаров) стандартные методы могут вызывать Исключение: Недостаточно памяти. В таких случаях используйте потоковую запись через временные файлы:

Использовать ЗаписьXMLФайл вместо ЗаписьXML|

Разбивать строку на фрагменты по 10–50 КБ|

Отключать буферизацию для ускорения записи|

Проверять свободное место на диске перед операцией-->

ИмяВременногоФайла = ПолучениеИмениВременногоФайла("xml");

// Запись во временный файл

ЗаписьXML = Новый ЗаписьXMLФайл(ИмяВременногоФайла);

ЗаписьXML.ЗаписатьОбъявлениеXML();

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

// Построчная запись (например, из текстового файла)

ЧтениеТекста = Новый ЧтениеТекста(ИмяИсходногоФайла);

Пока ЧтениеТекста.ПрочитатьСтроку() Цикл

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

ЗаписьXML.ЗаписатьТекст(ЧтениеТекста.ТекущаяСтрока);

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

КонецЦикла;

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

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

// Чтение результата обратно в строку (если нужно)

ЧтениеXML = Новый ЧтениеXMLФайл(ИмяВременногоФайла);

РезультатXML = ЧтениеXML.Прочитать();

⚠️ Внимание: При потоковой обработке следите за КодировкойТекста — если исходная строка в Windows-1251, а XML записывается в UTF-8, символы кириллицы превратятся в "кракозябры". Используйте ПреобразоватьКодировку():

ТекстUTF8 = ПреобразоватьКодировку(ИсходныйТекст, КодировкаТекста.ANSI, КодировкаТекста.UTF8);

5. Внешние компоненты для сложных задач

Если стандартные средства не справляются (например, нужно поддерживать XSLT-преобразования или работать с SOAP), подключите внешние компоненты:

  • 🔹 1C:XML-конвертер — платное решение от фирмы 1С для сложных интеграций (поддерживает XSD 1.1, XPath 2.0).
  • 🔹 LibXML2 — бесплатная библиотека для Linux-серверов (требует настройки через ВнешняяКомпонента).
  • 🔹 MSXML — встроенная в Windows библиотека (доступна через COMОбъект("Msxml2.DOMDocument")).

Пример использования MSXML:

// Создаем COM-объект

DOMDocument = Новый COMОбъект("Msxml2.DOMDocument.6.0");

DOMDocument.async = Ложь;

// Загружаем строку как XML

Если НЕ DOMDocument.loadXML(СтрокаXML) Тогда

Сообщить("Ошибка XML: " + DOMDocument.parseError.reason);

КонецЕсли;

// Преобразуем в строку с отступами

DOMDocument.setProperty("SelectionNamespaces", "xmlns:ns='urn:schema'");

РезультатXML = DOMDocument.xml;

Преимущества внешних компонент:

  • 📌 Поддержка XPath, XSLT, XQuery.
  • 📌 Валидация по сложным XSD-схемам (например, для ЭДО или Маркировки).
  • 📌 Высокая производительность при работе с большими файлами (>100 МБ).
⚠️ Внимание: Внешние компоненты могут конфликтовать с антивирусами (например, Kaspersky блокирует MSXML как "потенциально опасный"). Перед использованием настройте исключения в политиках безопасности.

- Тип входных данных (строка/JSON/CSV)

- Кодировка исходника и результата

- Флаг "Экранировать специальные символы"

Это сэкономит время при повторном использовании кода.-->

6. Типичные ошибки и их решение

При преобразовании строк в XML разработчики часто сталкиваются с следующими проблемами:

Ошибка Причина Решение
Недопустимый символ в XML Строка содержит &, < или > без экранирования Используйте ЗаписьXML.ЗаписатьТекст() вместо ЗаписатьСырыеДанные()
Некорректная кодировка Исходная строка в ANSI, а XML записывается в UTF-8 Примените ПреобразоватьКодировку() перед записью
Нарушена структура XML Не закрыт тег или неправильная вложенность Проверьте результат через валидатор XML
Ошибка XDTO: Не найден пакет Не загружена XSD-схема Укажите полный путь к файлу схемы в ФабрикаXDTO.ЗагрузитьПакетXDTO()

Для отладки используйте логирование промежуточных результатов:

Процедура ЛогXML(Сообщение, Данные)

ЗаписьЛога = Новый ЗаписьТекста;

ЗаписьЛога.Открыть("C:\logs\xml_convert.log", КодировкаТекста.UTF8, Истина);

ЗаписьЛога.ЗаписатьСтроку(Формат(ТекущаяДата(), "ДФ=yyyy-MM-dd HH:mm:ss") + " | " + Сообщение);

ЗаписьЛога.ЗаписатьСтроку(Данные);

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

КонецПроцедуры

💡

Всегда проверяйте результирующий XML на валидность перед отправкой в внешнюю систему. Даже если код отработал без ошибок, XML может быть сформирован некорректно (например, с лишними пробелами или неверной кодировкой).

FAQ: Частые вопросы

Как преобразовать строку с переносами строк в XML?

Используйте СтрЗаменить() для замены символов Cимволы.ПС (перенос строки) на тег <br/> или другой разделитель:

ТекстБезПереносов = СтрЗаменить(ИсходныйТекст, Символы.ПС, "<br/>");

Если переносы должны сохраниться как есть, экранируйте их:

ТекстДляXML = СтрЗаменить(ИсходныйТекст, Символы.ПС, "
");
Можно ли преобразовать XML обратно в строку?

Да, используйте ЧтениеXML:

ЧтениеXML = Новый ЧтениеXML;

ЧтениеXML.УстановитьСтроку(XMLСтрока);

Результат = ЧтениеXML.Прочитать(); // Вернет Структуру или Массив

Для извлечения текстового содержимого тега:

ЧтениеXML.Прочитать();

Текст = ЧтениеXML.Значение;

Как добавить атрибуты к тегам в XML?

В ЗаписьXML используйте метод ЗаписатьАтрибут():

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

ЗаписьXML.ЗаписатьАтрибут("артикул", "12345");

ЗаписьXML.ЗаписатьТекст("Наименование товара");

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

В XDTO атрибуты добавляются через УстановитьАтрибут():

Элемент.УстановитьАтрибут("http://schema.org/attr", "значение");
Почему в XML вместо кириллицы отображаются знаки вопроса?

Это проблема с кодировкой. Убедитесь, что:

  1. В ЗаписьXML установлена кодировка UTF-8:
  2. ЗаписьXML.Кодировка = КодировкаТекста.UTF8;
  3. Исходная строка преобразована в UTF-8:
  4. ТекстUTF8 = ПреобразоватьКодировку(ИсходныйТекст, КодировкаТекста.ANSI, КодировкаТекста.UTF8);
  5. В XML-декларации указано encoding="UTF-8":
  6. ЗаписьXML.ЗаписатьОбъявлениеXML("1.0", "UTF-8");
Как сжать XML перед отправкой?

Используйте GZip-сжатие через ПотокВПамяти:

// Сжимаем XML

ПотокXML = Новый ПотокВПамяти();

ЗаписьXML = Новый ЗаписьДвоичныхДанных(ПотокXML);

ЗаписьXML.ЗаписатьСтроку(РезультатXML, КодировкаТекста.UTF8);

// Создаем GZip-поток

ПотокGZip = Новый ПотокВПамяти();

ЗаписьGZip = Новый ЗаписьДвоичныхДанных(ПотокGZip);

ЗаписьСжатия = Новый ЗаписьСжатияДанных(ЗаписьGZip, ВидСжатияДанных.GZip);

// Копируем данные

ПотокXML.УстановитьПозицию(0);

Пока ПотокXML.Позиция() < ПотокXML.Размер() Цикл

Буфер = ПотокXML.Прочитать(1024);

ЗаписьСжатия.Записать(Буфер);

КонецЦикла;

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

// Получаем сжатые данные

СжатыйXML = ПотокGZip.ЗакрытьИПолучитьДанные();

Для распаковки используйте ЧтениеСжатияДанных.