В процессе интеграции 1С с внешними системами часто возникают ситуации, когда необходимо разобрать XML-файл, структура которого заранее неизвестна. Особенно остро проблема стоит, когда в XML-тегах присутствуют атрибуты xsi:type. Стандартный механизм ФабрикаXDTO при попытке прочитать такой файл выдает ошибку, так как требует наличия описания типов в пакетах конфигурации. Разберем, как обойти это ограничение и какие методы наиболее эффективны.
Механизм XDTO в 1С построен на строгой типизации. Когда парсер встречает атрибут xsi:type, он обращается к загруженным пакетам XDTO, чтобы найти определение типа. Если пакет не подключен или тип не найден — возникает исключение. К сожалению, в платформе не предусмотрено «волшебной кнопки» или флага, который бы принудительно игнорировал типизацию и превращал все узлы в anyType.
Если структура файла заранее неизвестна или динамически меняется, самым надежным способом является использование ЧтениеDOM. Этот метод не требует предварительной регистрации схем XSD и позволяет гибко работать с любыми узлами.
Рассмотрим, как прочитать такой XML через DOM:
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ИмяФайла);
ПостроительDOM = Новый ПостроительDOM;
ДокументDOM = ПостроительDOM.Прочитать(Чтение);
Чтение.Закрыть();
// Пример получения данных из узла
СписокЭлементов = ДокументDOM.ПолучитьЭлементыПоИмени("СуммаДокумента");
Если СписокЭлементов.Количество() > 0 Тогда
Сумма = СписокЭлементов.Получить(0).ТекстовоеСодержимое;
КонецЕсли;
Преимущество этого подхода заключается в том, что парсер DOM просто считывает иерархию элементов, игнорируя типизацию xsi, которая так мешает ФабрикеXDTO.
Если вам все же критически важно использовать ФабрикуXDTO для удобной работы через «точку» (например, Объект.Свойство), можно временно удалить атрибуты типов из строки XML перед парсингом. Однако стоит помнить, что простая строковая замена может повредить данные.
Рекомендуется использовать безопасную замену или преобразование:
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ИмяФайла);
ТекстXML = ТекстовыйДокумент.ПолучитьТекст();
// Заменяем префикс, чтобы типизация перестала конфликтовать
ТекстXML = СтрЗаменить(ТекстXML, "xsi:type", "deleted_type");
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(ТекстXML);
// Теперь фабрика не будет спотыкаться о типы
ОбXDTO = ФабрикаXDTO.ПрочитатьXML(Чтение);
Внимание: Этот метод может привести к потере данных, если в самом XML-документе встречаются значения, содержащие строку «xsi:type». Используйте его только в контролируемой среде.
Для больших файлов строковые функции работают медленно. Более профессиональным решением является применение объекта ПреобразованиеXSL. Вы можете создать простой XSLT-шаблон, который при чтении файла будет вырезать узлы xsi:type на лету. Это позволяет работать с документом на уровне структуры, что гораздо быстрее и безопаснее, чем обычная замена текста.
ЧтениеDOM позволяет легко перемещаться по дереву элементов и получать их текстовое содержимое.Таким образом, для большинства задач по разбору нетипизированных или «неправильных» XML-файлов лучшим выбором будет использование ПостроителяDOM, так как он обеспечивает максимальную гибкость без необходимости изменения конфигурации или создания тысяч вспомогательных файлов схем.