Как прочитать XML-файл с клиента и обработать его на сервере 1С

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

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

Разберем детально, почему возникают эти проблемы, и рассмотрим проверенные способы корректного чтения и обработки XML-файлов.

Почему возникают ошибки при работе с файлами между клиентом и сервером

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

  1. Изоляция файловых систем: Серверный процесс 1С не имеет прямого доступа к локальным дискам рабочей станции пользователя. Путь вроде C:\Data\file.xml, переданный в серверную процедуру, будет искаться сервером на его собственном диске.
  2. Несериализуемость объекта ЧтениеXML: Этот объект предназначен для последовательного чтения потока XML и не может быть передан через границу клиент-серверного вызова.
  3. Ошибки в синтаксисе методов: Метод ЧтениеXML.Прочитать() не принимает путь к файлу в качестве параметра, а лишь считывает следующий узел уже открытого потока.

Способ 1. Использование временного хранилища (рекомендуемый платформенный подход)

Рассмотрим основной и наиболее универсальный метод передачи файлов в управляемом приложении. Файл отправляется во временное хранилище на клиенте, после чего сервер считывает его двоичные данные без сохранения на постоянный диск.

Посмотрим на реализацию выбора и передачи файла:


&НаКлиенте
Процедура ВыбратьИЗагрузитьФайл(Команда)
    
    ПараметрыДиалога = Новый ПараметрыДиалогаПомещенияФайлов;
    ПараметрыДиалога.Фильтр = "Файлы XML (*.xml)|*.xml";
    ПараметрыДиалога.Заголовок = "Выберите файл для загрузки";
    
    Оповещение = Новый ОписаниеОповещения("ВыбратьИЗагрузитьФайлЗавершение", ЭтотОбъект);
    
    НачатьПомещениеФайлаНаСервер(Оповещение, , , ПараметрыДиалога, УникальныйИдентификатор);
    
КонецПроцедуры

&НаКлиенте
Процедура ВыбратьИЗагрузитьФайлЗавершение(ОписаниеФайла, ДополнительныеПараметры) Экспорт
    
    Если ОписаниеФайла = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Передаем адрес временного хранилища на сервер
    ПрочитатьXMLНаСервере(ОписаниеФайла.Адрес);
    
КонецПроцедуры

Теперь разберем обработку полученных данных на сервере. В современных версиях платформы чтение можно выполнить напрямую из потока памяти, не создавая временных файлов на диске сервера:


&НаСервере
Процедура ПрочитатьXMLНаСервере(АдресВременногоХранилища)
    
    ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВременногоХранилища);
    
    // Открываем поток для чтения данных из памяти
    Поток = ДвоичныеДанные.ОткрытьПотокДляЧтения();
    
    ЧтениеXML = Новый ЧтениеXML;
    ЧтениеXML.ОткрытьПоток(Поток);
    
    Пока ЧтениеXML.Прочитать() Цикл
        Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
            ИмяЭлемента = ЧтениеXML.Имя;
            // Обработка данных узлов XML
        КонецЕсли;
    КонецЦикла;
    
    ЧтениеXML.Закрыть();
    
    // Очищаем временное хранилище после завершения обработки
    УдалитьИзВременногоХранилища(АдресВременногоХранилища);
    
КонецПроцедуры

Способ 2. Чтение файла в строку на клиенте и передача на сервер

Проанализируем вариант для работы с небольшими XML-документами (размером в несколько мегабайт). Файл считывается в строковую переменную на стороне клиента, после чего строка передается параметром в серверную процедуру.

Посмотрим на пример клиентского кода с использованием объекта ЧтениеТекста:


&НаКлиенте
Процедура ПрочитатьЧерезСтроку(ПутьКФайлу)
    
    ЧтениеТекста = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.UTF8);
    СтрокаXML = ЧтениеТекста.Прочитать();
    ЧтениеТекста.Закрыть();
    
    Если Не ПустаяСтрока(СтрокаXML) Тогда
        РазобратьСтрокуXMLНаСервере(СтрокаXML);
    КонецЕсли;
    
КонецПроцедуры

На сервере инициализируем парсер с помощью метода УстановитьСтроку:


&НаСервере
Процедура РазобратьСтрокуXMLНаСервере(СтрокаXML)
    
    ЧтениеXML = Новый ЧтениеXML;
    ЧтениеXML.УстановитьСтроку(СтрокаXML);
    
    Пока ЧтениеXML.Прочитать() Цикл
        Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
            // Чтение структуры документа
        КонецЕсли;
    КонецЦикла;
    
    ЧтениеXML.Закрыть();
    
КонецПроцедуры

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

Способ 3. Парсинг на клиенте с передачей готовых структур

Разберем еще один подход, который позволяет снять нагрузку с сервера при разборе тяжелых XML-структур в тонком или толстом клиенте:

  1. На клиенте открываем локальный файл с помощью ЧтениеXML.ОткрытьФайл(ПутьКФайлу).
  2. Считываем данные и упаковываем их в сериализуемые коллекции платформы (например, в Массив структур или соответствий).
  3. Передаем на сервер только результирующий массив данных для выполнения записи в информационную базу.

Такой подход минимизирует объем данных, пересылаемых по сети, и позволяет серверу сосредоточиться исключительно на транзакционной записи в базу данных.

← На главную