Как получить и отследить изменения структуры XML-файла в 1С

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

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

Способ 1: Создание «отпечатка» структуры через быстрое последовательное чтение

Для больших файлов использование ПостроительDOM может быть избыточным и медленным, так как он загружает всё дерево документа в оперативную память. Если наша задача — только проверить, не изменился ли «скелет» файла, проанализируем метод последовательного чтения с использованием объекта ЧтениеXML.

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


Функция ПолучитьХэшСтруктурыXML(ПутьКФайлу)
    Чтение = Новый ЧтениеXML;
    Чтение.ОткрытьФайл(ПутьКФайлу);
    
    СтрокаСтруктуры = "";
    
    Пока Чтение.Прочитать() Цикл
        ТипУзла = Чтение.ТипУзла;
        
        Если ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
            СтрокаСтруктуры = СтрокаСтруктуры + "/Start:" + Чтение.Имя;
            
            // Собираем атрибуты, так как их состав — часть структуры
            Пока Чтение.ПрочитатьАтрибут() Цикл
                СтрокаСтруктуры = СтрокаСтруктуры + "/Attr:" + Чтение.Имя;
            КонецЦикла;
            
        ИначеЕсли ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
            СтрокаСтруктуры = СтрокаСтруктуры + "/End:" + Чтение.Имя;
        КонецЕсли;
    КонецЦикла;
    
    Чтение.Закрыть();
    
    // Используем стандартную функцию получения хэша (MD5)
    Хэширование = Новый ХешированиеДанных(ХешФункция.MD5);
    Хэширование.Добавить(СтрокаСтруктуры);
    Возврат НРег(СтрЗаменить(Строка(Хэширование.ХешСумма), " ", ""));
КонецФункции

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

Способ 2: Динамическая генерация и проверка через Схему XSD

Объект СхемаXSD в 1С предназначен для описания правил построения XML. Хотя платформа не предоставляет прямой функции «СоздатьСхемуИзФайла», мы можем программно наполнить объект СхемаXSD, итерируя по узлам. Однако более практичный подход — использовать уже имеющуюся схему для валидации.

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


// Пример валидации файла по схеме
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ПутьКФайлу);

Схемы = Новый СерияСхемXML;
Схемы.Добавить(ПутьКСхемеXSD);

Попытка
    Чтение.Проверить(Схемы);
    Пока Чтение.Прочитать() Цикл
        // Если структура нарушена, метод Проверить() вызовет исключение
    КонецЦикла;
    Сообщить("Файл соответствует структуре.");
Исключение
    Сообщить("Ошибка структуры: " + ОписаниеОшибки());
КонецПопытки;

Важный момент: Если схемы нет, её можно создать один раз с помощью сторонних сервисов генерации XSD по примеру XML-файла и в дальнейшем использовать в 1С для контроля.

Способ 3: Использование фабрики XDTO для «мягкой» проверки

Объекты XDTO (XML Data Transfer Objects) — это мощный механизм 1С для работы со структурированными данными. Мы можем создать в конфигурации Пакет XDTO, описывающий ожидаемую структуру. При чтении XML через фабрику XDTO, платформа автоматически сопоставляет узлы файла с типами пакета.

Проанализируем ситуацию: если во входящем файле появится узел, не описанный в типе XDTO, или пропадет обязательное свойство, метод ПрочитатьXML() выдаст ошибку. Рассмотрим пример кода:


Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ПутьКФайлу);

Попытка
    // Пытаемся прочитать объект, используя тип из нашего пакета XDTO
    Данные = ФабрикаXDTO.ПрочитатьXML(Чтение, ФабрикаXDTO.Тип("http://www.my-namespace.ru", "MyRootElement"));
    // Если чтение прошло успешно, структура валидна
Исключение
    ТекстОшибки = ИнформацияОбОшибке().Описание;
    ЗаписатьЛог("Изменение структуры XML: " + ТекстОшибки);
КонецПопытки;

Этот метод удобен тем, что он совмещает проверку структуры и само чтение данных в объектную модель 1С, что экономит время на двойном парсинге.

Способ 4: Канонизация и извлечение скелета через ПостроительDOM

Если нам нужно не просто сравнить хэш, а понять, какой именно узел добавился, рассмотрим использование ПостроительDOM. Мы можем извлечь все уникальные пути к узлам (XPath-подобные структуры) и сохранить их в список.

Выясним причину, почему это эффективно: сравнивая два списка уникальных путей (эталонный и текущий), мы можем точно сказать пользователю: «Добавился новый узел по пути /Root/Orders/Order/Discount».


Функция ПолучитьДеревоПутей(ДокументDOM, ТекущийПуть = "", СписокПутей = Неопределено)
    Если СписокПутей = Неопределено Тогда
        СписокПутей = Новый СписокЗначений;
    КонецЕсли;
    
    Для Каждого Узел Из ДокументDOM.ДочерниеУзлы Цикл
        Если Узел.ТипУзла = ТипУзлаDOM.Элемент Тогда
            НовыйПуть = ТекущийПуть + "/" + Узел.ИмяУзла;
            Если СписокПутей.НайтиПоЗначению(НовыйПуть) = Неопределено Тогда
                СписокПутей.Добавить(НовыйПуть);
            КонецЕсли;
            ПолучитьДеревоПутей(Узел, НовыйПуть, СписокПутей);
        КонецЕсли;
    КонецЦикла;
    
    Возврат СписокПутей;
КонецФункции

Используя этот рекурсивный обход, мы формируем «карту» документа. Преимущество этого метода в наглядности — вы всегда видите полную иерархию всех возможных тегов файла.

Рекомендации по выбору метода

  1. Если файлы огромные (десятки и сотни мегабайт), используйте Способ 1 (Хэширование через ЧтениеXML). Это самый быстрый вариант, не нагружающий память.
  2. Если вам важна строгая типизация (например, проверка, что в поле "Цена" пришло число, а не строка), выбирайте Способ 2 (XSD) или Способ 3 (XDTO).
  3. Если вы разрабатываете гибкий интеграционный шлюз, который должен подсказывать администратору, что именно изменилось в формате обмена, реализуйте Способ 4 (Сравнение путей через DOM).

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

← На главную