Как исправить ошибку «Extra content at the end of the document» при синхронизации 1С:ERP и 1С:ЗУП?

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

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

Рассмотрим детально одну из классических ошибок обмена:


Ошибка разбора XML: - [248003,37]
Фатальная ошибка: 
Extra content at the end of the document
SystemId: file://C:/Users/Service-1C/AppData/Local/Temp/Exchange82 {...}/Message_ЗК_...xml

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

Почему возникает ошибка «Extra content at the end of the document»?

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

Проанализируем основные технические причины этой проблемы:

  1. Несовместимость версий схем EnterpriseData. Если отправляющая информационная база (например, 1С:ЗУП) формирует пакет данных по более новой схеме XDTO, а принимающая база (1С:ERP) ожидает структуру предыдущей версии, то при попытке сопоставить типы через ФабрикаXDTO.Тип происходит сбой позиционирования указателя чтения в XML-потоке.
  2. Проблема «обрезанных» или «склеенных» файлов в БСП. Это наиболее частый скрытый баг файлового обмена в Библиотеке стандартных подсистем (БСП). Если новый файл выгрузки по размеру оказывается меньше, чем предыдущий файл в той же временной папке, при перезаписи операционная система может скопировать новые данные поверх старых, не затерев «хвост» старого файла. Парсер считывает закрывающий тег нового сообщения, но видит после него остатки предыдущего пакета обмена, что и приводит к ошибке Extra content.
  3. Спецсимволы в данных. Наличие непечатных знаков (ASCII-символов с кодами меньше 32), битых кодировок, некорректно экранированных амперсандов (&) или угловых скобок в реквизитах справочников нарушает структуру XML-файла, из-за чего парсер теряет границы элементов.

Специфика обмена справочника «Банки» через XDTO

Пользователи часто обращают внимание, что в тексте ошибки фигурирует объект: Справочник.Банки, хотя в структуре метаданных ERP и ЗУП такого справочника нет — там используется Справочник.КлассификаторБанков (или Справочник.БИК в старых версиях).

Дело в том, что при обмене через универсальный формат EnterpriseData физические объекты метаданных транслируются в сущности XDTO-пакета. Тип Справочник.КлассификаторБанков сопоставляется со схемой XDTO-объекта Справочник.Банки. Любое несовпадение реквизитов классификатора в разных версиях программ (например, изменения в структуре адресов или признаков филиалов банков) вызывает конфликт схем при чтении.

Рассмотрим по шагам методы исправления этой ошибки.

Способ 1. Синхронизация релизов баз и правил регистрации (Рекомендуемый)

Самый надежный и правильный способ устранить ошибку — привести конфигурации-участники обмена к актуальным релизам. В новых версиях программ поставляются обновленные правила регистрации объектов и актуальные XDTO-пакеты EnterpriseData.

Выполним следующие действия:

  1. Проверим текущие версии конфигураций в меню «О программе». Разработчики из 1С регулярно обновляют структуры XML-обмена. Использование устаревшего релиза одной из баз гарантированно приведет к ошибкам десериализации.
  2. Обновим конфигурацию 1С:ЗУП и 1С:ERP до актуальных релизов.
  3. После обновления правила обмена и регистрации объектов внутри планов обмена автоматически обновятся на совместимые версии. Перенастройка самой синхронизации при этом не требуется — платформа продолжит обмен в штатном режиме.

Способ 2. Временное исключение банков из состава отправляемых данных

Если быстро обновить конфигурации невозможно, а восстановить работоспособность синхронизации нужно срочно, лучшим решением будет исключить справочник банков из обмена. Справочник банков обновляется напрямую с классификатора ЦБ РФ в каждой базе автономно, поэтому переносить его между базами нет технологической необходимости.

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

  1. В базе-источнике перейдем в раздел Администрирование — Синхронизация данных.
  2. Откроем список настроенных синхронизаций, выделим нужный обмен и нажмем кнопку Состав отправляемых данных (иконка с синим карандашом).
  3. В открывшемся дереве объектов найдем элемент Справочник.КлассификаторБанков.
  4. Нажмем правую кнопку мыши и выберем пункт Отменить регистрацию всех объектов данного типа.
  5. Для предотвращения повторной автоматической регистрации этого объекта перейдем в настройки правил отправки данных для данной синхронизации и снимим флажок с выгрузки классификаторов, либо настроим ручной запрет выгрузки справочника банков через правила регистрации.

Способ 3. Очистка кэша обмена и временных файлов

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

  1. Остановим сеансы обмена (если синхронизация выполняется под регламентным заданием, временно отключим его).
  2. Перейдем на сервере 1С (или на локальном ПК, если база файловая) в каталог временных файлов пользователя, под которым запускается сеанс обмена. Обычно он находится по пути: C:\Users\[ИмяПользователя]\AppData\Local\Temp\.
  3. Найдем и полностью удалим папки с префиксом Exchange82 (например, Exchange82 {0BFF4E7F-...}).
  4. Очистим кэш конфигурации на рабочем компьютере, чтобы принудительно обновить схемы XDTO в памяти платформы.

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

Часто сбой вызывают «битые» непечатные символы, которые попадают в базу при копировании информации из внешних источников (например, из PDF-документов или писем). Проанализируем базу на наличие таких спецсимволов. Для этого можно воспользоваться внешней обработкой «Групповое изменение реквизитов» или написать небольшой программный код в консоли кода:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	КлассификаторБанков.Ссылка КАК БанкСсылка,
    |	КлассификаторБанков.Наименование КАК Наименование
    |ИЗ
    |	Справочник.КлассификаторБанков КАК КлассификаторБанков";

Результат = Запрос.Выполнить().Выбрать();
Пока Результат.Следующий() Цикл
    ТекстНаименования = Результат.Наименование;
    Для Индекс = 1 По СтрДлина(ТекстНаименования) Цикл
        КодСимвола = КодСимвола(ТекстНаименования, Индекс);
        // Символы с кодом меньше 32 (кроме перевода строки и табуляции) недопустимы в XML
        Если КодСимвола < 32 И КодСимвола <> 9 И КодСимвола <> 10 И КодСимвола <> 13 Тогда
            Сообщить("В банке " + Результат.БанкСсылка + " найден спецсимвол с кодом: " + КодСимвола);
        КонецЕсли;
    КонецЦикла;
КонецЦикла;

Если обработка зафиксирует дефектные элементы, отредактируем их наименования вручную, удалив невидимые спецсимволы, и повторим попытку синхронизации.

Способ 5. Исправление бага перезаписи файлов в коде БСП (для разработчиков)

Если обмен настроен через файловый каталог и ошибка дублируется регулярно, мы можем скорректировать программный код БСП в конфигурации, чтобы гарантированно избежать наложения данных при копировании XML-сообщений.

В общем модуле ТранспортСообщенийОбменаFILE найдем процедуру, отвечающую за копирование подготовленного файла обмена в целевую директорию, и заменим стандартный вызов метода КопироватьФайл на безопасный вариант с предварительным принудительным удалением файла-приемника:


// Безопасная перезапись файла обмена для исключения эффекта "Extra content"
ФайлПриемник = Новый Файл(ИмяФайлаПриемника);
Если ФайлПриемник.Существует() Тогда
    Попытка
        УдалитьФайлы(ИмяФайлаПриемника);
    Исключение
        ЗаписьЖурналаРегистрации("ОбменДанными", УровеньЖурналаРегистрации.Предупреждение, , , 
            "Не удалось удалить старый файл перед копированием: " + ОписаниеОшибки());
    КонецПопытки;
КонецЕсли;

КопироватьФайл(ИмяФайлаИсточника, ИмяФайлаПриемника);

Этот простой шаг гарантирует, что новый XML-файл всегда будет создаваться «с чистого листа», и в его конце никогда не окажется мусорных тегов от предыдущих транзакций.

← На главную