При интеграции систем часто требуется гарантировать, что входящий или исходящий XML-документ строго соответствует регламентированной схеме XSD. Нередко разработчики сталкиваются с ситуацией, когда документ с произвольной структурой успешно проходит чтение, платформа не сообщает об ошибках либо, напротив, выдает интерактивные окна с сообщениями вместо записи в лог. Кроме того, использование устаревших COM-объектов (например, MSXML2.DOMDocument) блокируется службами безопасности или становится невозможным при работе сервера на операционных системах Linux.
Разберем, как реализовать надежную, кроссплатформенную валидацию средствами платформы 1С:Предприятие с помощью механизмов XDTO, выясним причины типичных ошибок и рассмотрим альтернативные подходы.
Проанализируем две основные проблемы, из-за которых проверка XML по схеме не работает или завершается ошибкой еще на этапе инициализации схемы:
http://www.w3.org/2001/XMLSchema является служебным стандартом консорциума W3C. Оно указывает платформе, что перед ней находится определение типов данных, элементов и атрибутов XSD (теги xs:schema, xs:element, xs:complexType). Если заменить этот URI на собственную строку, платформа 1С перестанет воспринимать файл как схему и выдаст синтаксическую ошибку загрузки. Собственное пространство имен документа необходимо указывать только в атрибуте targetNamespace схемы.ФабрикаXDTO метода Проверить() нет. Проверка выполняется у полученного экземпляра — объекта ОбъектXDTO. Если пытаться валидировать документ через интерактивные функции или вызывать проверку без привязки к конкретному типу схемы, платформа прочитает XML как универсальный неунифицированный набор данных (тип anyType), пропустив все структурные ограничения.Разберем по шагам создание собственной фабрики XDTO, чтение файла и проверку ограничений схемы с перехватом ошибок в журнал регистрации.
Шаг 1. Создание фабрики XDTO на основе файла схемы.
Для того чтобы 1С проверяла структуру документа строго по вашему XSD, создадим изолированную фабрику XDTO. Посмотрим на пример кода загрузки схемы:
ЧтениеСхемы = Новый ЧтениеXML;
ЧтениеСхемы.ОткрытьФайл(ПутьКСхемеXSD);
СхемаXSD = ФабрикаXDTO.ЭкспортНастройкиXML().СхемыXML.Прочитать(ЧтениеСхемы);
ЧтениеСхемы.Закрыть();
МассивСхем = Новый Массив;
МассивСхем.Добавить(СхемаXSD);
ЛокальнаяФабрика = СоздатьФабрикуXDTO(МассивСхем);
Если схема состоит из нескольких зависимых файлов, использующих директивы xs:import или xs:include, прочитаем все файлы схемы и передадим их в массив в порядке зависимостей.
Шаг 2. Чтение XML с валидацией базовой структуры.
При вызове метода ПрочитатьXML() у созданной фабрики крайне важно передавать вторым параметром тип корневого элемента XDTO. Если тип не указан, платформа попытается сопоставить его автоматически, что при несовпадении пространств имен может привести к отсутствию контроля структуры.
ЧтениеДокумента = Новый ЧтениеXML;
ЧтениеДокумента.ОткрытьФайл(ПутьКXML);
// Получаем тип корневого элемента из созданной фабрики
// ПространствоИменДокумента должно соответствовать targetNamespace схемы
ТипКорня = ЛокальнаяФабрика.Тип(ПространствоИменДокумента, "ИмяКорневогоТега");
Попытка
ОбъектДокумента = ЛокальнаяФабрика.ПрочитатьXML(ЧтениеДокумента, ТипКорня);
Исключение
ЧтениеДокумента.Закрыть();
ТекстОшибки = "Ошибка структуры XML при чтении: " + ОписаниеОшибки();
ЗаписьЖурналаРегистрации("Валидация XML", УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки);
ВызватьИсключение ТекстОшибки;
КонецПопытки;
ЧтениеДокумента.Закрыть();
На этом этапе платформа автоматически проверяет обязательное наличие тегов, корректность вложенности и соответствие базовым типам (число, дата, булево). В случае нарушения структуры метод немедленно генерирует исключение.
Шаг 3. Проверка фасетов и ограничений через ОбъектXDTO.Проверить().
После успешного чтения объекта проверим логические ограничения схемы: длину строк (minLength, maxLength), диапазоны чисел (minInclusive, maxInclusive), количество повторений (minOccurs, maxOccurs) и регулярные выражения (pattern). Метод Проверить() вызывается непосредственно у полученного объекта ОбъектXDTO.
Чтобы избежать появления диалоговых окон и модальных предупреждений, обернем вызов в блок Попытка...Исключение:
Попытка
ОбъектДокумента.Проверить();
Исключение
ТекстОшибки = "Документ не прошел валидацию по XSD: " + ОписаниеОшибки();
ЗаписьЖурналаРегистрации("Валидация XML", УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки);
// При необходимости можно прервать дальнейшую обработку
ВызватьИсключение ТекстОшибки;
КонецПопытки;
Рассмотрим нюансы работы штатного механизма XDTO в 1С:
ОбъектXDTO.Проверить() генерирует исключение на первой встреченной невалидной конструкции. Получить сразу полный перечень всех некорректных узлов XML за один вызов не удастся.mixed="true"), некоторых вариантов xs:redefine или циклических зависимостей в схемах.Если требуется получать исчерпывающий список всех ошибок схемы за один проход или схема использует сложные конструкции XSD 1.1, рассмотрим внешние инструменты, работающие как на Windows, так и на Linux:
libxml2 доступен во всех популярных дистрибутивах Linux и существует для Windows. Запуск утилиты можно выполнить через ЗапуститьПриложение(). Команда xmllint --noout --schema schema.xsd document.xml возвращает код 0 при успешной валидации, а в поток ошибок выводит полный список всех нарушений структуры со ссылками на строки файла.libxml2 или Xerces-C++, подключается непосредственно в процесс сервера 1С и позволяет валидировать файлы на высокой скорости без создания временных процессов операционной системы.HTTPСоединение. Такой подход изолирует сложные схемы и снимает вычислительную нагрузку с сервера 1С.