Как упаковать текстовый документ или файл в XML в 1С?

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

При интеграции 1С с внешними информационными системами часто возникает задача передать текстовый или бинарный файл (например, документ MS Word, лог-файл или HTML-страницу) внутри XML-пакета. Напрямую записать бинарный файл или текст со спецсимволами в XML нельзя, так как это нарушит структуру XML-документа. В этой статье мы подробно рассмотрим несколько способов решения этой задачи в зависимости от формата исходного файла и требований к результату.

Способ 1. Упаковка произвольного файла в XML через кодирование Base64

Если нам необходимо поместить любой файл (будь то плоский текст, картинка или документ Word .docx) внутрь XML-тега в виде текстовой строки, наиболее надежным решением является использование кодирования Base64. Этот стандарт преобразует двоичные данные в набор безопасных символов ASCII.

Рассмотрим пошагово, как реализовать этот алгоритм в коде 1С:

  1. Считаем исходный файл с диска и преобразуем его в объект ДвоичныеДанные.
  2. Выполним кодирование двоичных данных в строку формата Base64 с помощью встроенной функции платформы Base64Строка().
  3. Запишем полученную строку в тело XML-элемента, используя объект ЗаписьXML.

Проанализируем пример кода, реализующий этот метод:


// Укажем пути к исходному файлу и создаваемому XML
ПутьКФайлу = "C:\temp\instruction.docx";
ПутьКXML = "C:\temp\output.xml";

// 1. Читаем файл в двоичные данные
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);

// 2. Кодируем в строку Base64
СтрокаBase64 = Base64Строка(ДвоичныеДанныеФайла);

// 3. Записываем структуру XML
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ПутьКXML, "UTF-8");
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("FileTransfer");
ЗаписьXML.ЗаписатьАтрибут("FileName", "instruction.docx");

ЗаписьXML.ЗаписатьНачалоЭлемента("FileData");
ЗаписьXML.ЗаписатьТекст(СтрокаBase64); // Помещаем закодированные данные
ЗаписьXML.ЗаписатьКонецЭлемента(); // FileData

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

Важное ограничение: Обратите внимание, что при работе с файлами очень большого размера (сотни мегабайт) преобразование в единую Base64-строку может привести к значительному потреблению оперативной памяти на сервере 1С. Для очень больших файлов рекомендуется использовать потоковую передачу.

Способ 2. Запись плоского текста без кодирования через секции CDATA

Бывают ситуации, когда исходный документ представляет собой обычный текст (например, HTML-код, конфигурационные файлы или системные логи), который должен оставаться легко читаемым внутри XML-файла без кодирования в Base64. Однако такой текст может содержать служебные символы XML, такие как <, >, &, которые нарушат синтаксис XML-парсера.

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

Посмотрим на пример реализации с использованием метода ЗаписатьСекциюCDATA():


ТекстЛога = "Ошибка выполнения процесса: Значение1 < Значение2 & ОшибкаРегистрации";
ПутьКXML = "C:\temp\log_export.xml";

ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ПутьКXML, "UTF-8");
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("LogContainer");

// Записываем неформатированный текст в секцию CDATA
ЗаписьXML.ЗаписатьСекциюCDATA(ТекстЛога);

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

В результате работы этого кода текст будет автоматически обернут в конструкцию <![CDATA[ ... ]]>, что гарантирует его корректное чтение принимающей стороной.

Способ 3. Извлечение XML-данных напрямую из файлов MS Word (.docx)

Если перед нами стоит задача вытащить текстовое содержимое из документа MS Word (формата .docx) и перенести его в XML, нам не обязательно использовать стороннее программное обеспечение или COM-объекты. Файл формата .docx физически представляет собой обычный ZIP-архив, внутри которого вся структура и тексты хранятся в формате XML.

Мы можем программно распаковать этот архив средствами 1С и прочитать нужные файлы. Текстовое содержимое документа находится по пути word/document.xml.

Выясним, как прочитать этот файл без использования Windows-зависимых библиотек, что особенно актуально при работе на серверах под управлением Linux:


ПутьКDocx = "C:\temp\document.docx";
ПапкаРаспаковки = "C:\temp\unpacked_docx\";

// Распаковываем docx как обычный ZIP-архив
Архив = Новый ЧтениеZipФайла(ПутьКDocx);
Архив.ИзвлечьВсе(ПапкаРаспаковки, РежимВосстановленияПутейФайловZIP.Восстанавливать);
Архив.Закрыть();

// Путь к основному XML-файлу с текстом документа
ПутьКDocumentXML = ПапкаРаспаковки + "word/document.xml";

// Читаем извлеченный XML-файл
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКDocumentXML);

Пока ЧтениеXML.Прочитать() Цикл
    // Здесь мы можем анализировать структуру документа Word
    Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента И ЧтениеXML.Имя = "t" Тогда
        ЧтениеXML.Прочитать();
        Сообщить("Текст из Word: " + ЧтениеXML.Значение);
    КонецЕсли;
КонецЦикла;

ЧтениеXML.Закрыть();

Ограничение метода: При разборе извлеченных XML-файлов Word с использованием DOM-модели (объект ПостроительDOM) учитывайте платформенную особенность: элементы, содержащие только пробелы (например, теги форматирования пробелов между словами <w:t xml:space="preserve">), могут распознаваться как пустые строки. Это может привести к склеиванию слов при обратной сборке документа.

Способ 4. Конвертация Word в XML через COM-объект на Windows

Если база данных работает на операционной системе Windows и на компьютере (или сервере 1С) установлен пакет Microsoft Office, мы можем выполнить полноценное преобразование документа Word в формат WordprocessingML (стандартизированный XML-формат от Microsoft).

Для этого мы воспользуемся COM-соединением с приложением Word:


Попытка
    // Создаем COM-объект MS Word
    MSWord = Новый COMОбъект("Word.Application");
    MSWord.Visible = Ложь;
    
    // Открываем исходный документ
    Документ = MSWord.Documents.Open("C:\temp\document.docx");
    
    // Сохраняем в формате Word XML (код формата 11 или 12)
    // 11 соответствует формату Word XML Document
    Документ.SaveAs("C:\temp\document_converted.xml", 11);
    
    // Закрываем приложение
    Документ.Close();
    MSWord.Quit();
    
    Сообщить("Конвертация успешно завершена!");
Исключение
    Сообщить("Ошибка при конвертации документа: " + ОписаниеОшибки());
КонецПопытки;

Этот способ обеспечивает точное сохранение структуры и оформления документа, однако он полностью неприменим в Linux-среде и требует обязательного наличия лицензии Microsoft Office на стороне исполняющего код компьютера.

← На главную