Разработка и Конфигурация · 10 мин
Как разобрать XML-файл в 1С: способы чтения и обработки данных
Практическое руководство по разбору XML в 1С: ЧтениеXML, XDTO-пакеты, DOM-модель, обработка ошибок, примеры кода и типичные ошибки при загрузке данных.
XML остаётся основным форматом обмена данными между 1С и внешними системами: выгрузки из банков, каталоги поставщиков, ответы веб-сервисов, файлы ЭДО. Во встроенном языке 1С есть несколько инструментов разбора XML, и выбор конкретного зависит от размера файла, наличия схемы и задачи — нужно ли просто прочитать значения или провести их через строгую валидацию.
Три основных подхода — последовательное чтение через объект ЧтениеXML, загрузка всего документа в память через ПостроительDOM и работа через фабрику XDTO с описанием схемы. Каждый из них решает свой класс задач, и неправильный выбор приводит либо к перерасходу памяти на больших файлах, либо к избыточному коду там, где хватило бы десяти строк.
Ниже разобраны все три способа с примерами кода, обработкой ошибок и критериями выбора. Примеры ориентированы на управляемые формы и тонкий клиент, но работают и в обычном приложении.
Как выбрать способ разбора XML под задачу
Главные критерии выбора — объём файла, наличие XSD-схемы и то, как вы собираетесь обходить данные. Потоковое чтение подходит для файлов любого размера, но требует писать логику обхода вручную. DOM загружает весь документ в память как дерево объектов, что удобно для навигации, но рискованно при файлах в сотни мегабайт. XDTO даёт типизированный доступ к данным и автоматическую проверку по схеме, но требует подготовительной работы — описания пакета.
Сравнение способов разбора XML
Потоковое чтение, минимум памяти, подходит для больших файлов. Минус: только последовательный обход, нет возврата к предыдущим узлам.
Весь документ в памяти как дерево, свободная навигация по узлам. Минус: расход памяти пропорционален размеру файла.
Типизированные объекты, валидация по XSD-схеме, удобен для сложных структур. Минус: нужна схема и больше подготовительного кода.
На практике для разовой загрузки каталога товаров или выгрузки из сторонней системы чаще всего используют ЧтениеXML: код проще отлаживать, а ограничение на последовательный обход редко мешает — данные в файлах обмена обычно идут в логичном порядке.
Чтение XML через объект ЧтениеXML
Объект ЧтениеXML читает документ последовательно, узел за узлом, не загружая файл целиком в память. Это безопасный выбор по умолчанию, особенно когда размер файла заранее неизвестен. Основной цикл строится на методе Прочитать(), который перемещает курсор к следующему узлу, и проверке ТипУзла.
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл("C:\Обмен\catalog.xml");
Пока Чтение.Прочитать() Цикл
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
Если Чтение.Имя = "Товар" Тогда
Артикул = Чтение.ПолучитьАтрибут("Артикул");
КонецЕсли;
ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.Текст Тогда
ЗначениеУзла = Чтение.Значение;
КонецЕсли;
КонецЦикла;
Чтение.Закрыть();
Ключевые свойства на каждом шаге: Имя — имя текущего узла, Значение — текст внутри текстового узла, ПолучитьАтрибут("Имя") — значение атрибута по имени.
Всегда вызывайте Закрыть() после окончания чтения. Незакрытый объект удерживает файловый дескриптор, и на сервере при массовой обработке это приводит к блокировкам файлов и утечке ресурсов.
Разбор через ПостроительDOM
Когда структура документа сложная и нужно обращаться к узлам в произвольном порядке — например, сначала прочитать шапку, потом вернуться к реквизитам контрагента — удобнее загрузить документ в память как DOM-дерево. Для этого служат объекты ПостроительDOM и ЧтениеXML в связке.
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл("C:\Обмен\order.xml");
Построитель = Новый ПостроительDOM;
ДокументDOM = Построитель.Прочитать(Чтение);
Чтение.Закрыть();
УзлыТоваров = ДокументDOM.ПолучитьЭлементыПоИмени("Товар");
Для Каждого Узел Из УзлыТоваров Цикл
Наименование = Узел.ПолучитьАтрибут("Наименование");
КонецЦикла;
DOM-модель позволяет обращаться к дочерним элементам через ДочерниеУзлы, искать элементы по имени и перемещаться по дереву в любом направлении. Это удобно для анализа документов с непредсказуемым порядком элементов.
Ограничение принципиальное: весь файл размещается в оперативной памяти, причём DOM-представление занимает заметно больше места, чем исходный текст. Для файлов размером в десятки и сотни мегабайт такой подход может привести к аварийному завершению сеанса на сервере — в этом случае возвращайтесь к потоковому чтению.
Работа через фабрику XDTO
XDTO — механизм типизированной работы с XML на основе схемы. Если у вас есть XSD-файл от контрагента или вы обмениваетесь между конфигурациями 1С, XDTO даёт два преимущества: данные автоматически проверяются на соответствие схеме, а в коде вы работаете с объектами и свойствами, а не с именами узлов в строках.
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл("C:\Обмен\data.xml");
ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(Чтение);
Чтение.Закрыть();
Для Каждого СтрокаТовара Из ОбъектXDTO.Товары.Товар Цикл
Сообщить(СтрокаТовара.Наименование);
КонецЦикла;
Если схема не добавлена в конфигурацию как XDTO-пакет, платформа построит модель «на лету» по самому документу — это работает, но без валидации типов. Для строгого контроля пакет XDTO с описанием схемы добавляют в ветку «XDTO-пакеты» дерева конфигурации.
XDTO оправдан при регулярном обмене по фиксированному формату: банковские выписки, электронные документы, обмен с сайтом. Для разового разбора простого файла подготовка схемы окупается редко.
Обработка ошибок и проверка результата
XML из внешних источников регулярно содержит сюрпризы: неверная кодировка, обрезанный файл, неожиданные имена узлов, пустые значения там, где ожидается число. Минимальный защитный каркас — обёртка в Попытка..Исключение с информативным сообщением и обязательным закрытием чтения.
Чтение = Новый ЧтениеXML;
Попытка
Чтение.ОткрытьФайл(ИмяФайла);
Пока Чтение.Прочитать() Цикл
// логика разбора
КонецЦикла;
Чтение.Закрыть();
Исключение
Чтение.Закрыть();
ВызватьИсключение "Ошибка разбора XML: "
+ ОписаниеОшибки();
КонецПопытки;
Отдельно проверяйте результат преобразования типов. Конструкция Число("abc") вызовет исключение, поэтому нестандартные значения лучше обрабатывать через собственную функцию-обёртку с проверкой. Для дат в формате ISO используйте XMLЗначение(Тип("Дата"), СтрокаДаты) — он корректно разбирает стандартное представление.
Как проверить результат разбора
Совпадает с количеством элементов в файле (можно сверить поиском по имени узла в текстовом редакторе)
Часть записей потеряна — проверяйте условия в цикле и вложенность узлов
Суммы в базе совпадают с суммами в файле
Разделитель дробной части или пробелы-разделители разрядов сломали преобразование
Кириллица читается корректно
Крякозябры — файл в не-UTF кодировке, нужно указать кодировку при открытии
По кодировке: ОткрытьФайл() принимает вторым параметром кодировку. Если файл в windows-1251, а платформа читает его как UTF-8, русский текст превратится в нечитаемые символы. Кодировку обычно видно в объявлении <?xml version="1.0" encoding=".."?> в начале файла.
Загрузка данных в базу после разбора
Сам разбор XML — половина задачи; дальше значения нужно сопоставить с объектами базы. Типовой приём: по ключевому реквизиту (артикул, ИНН, код) искать существующий элемент справочника через НайтиПоКоду() или НайтиПоРеквизиту(), и при отсутствии создавать новый. Поиск по наименованию ненадёжен — расхождения в пробелах и регистре дают дубли.
При загрузке большого числа объектов записывайте их в транзакции разумного размера: либо одна транзакция на весь файл с откатом при ошибке, либо порционная запись с фиксацией каждые несколько сотен объектов. Полный откат безопаснее, но при обрыве на последней записи придётся повторять всю загрузку.
Отдельного упоминания заслуживают пространства имён. Если в файле узлы выглядят как <ns:Товар>, свойство Имя вернёт строку с префиксом, а ЛокальноеИмя — имя без него. Для устойчивости кода сравнивайте именно ЛокальноеИмя.
Частые вопросы
Чем отличается ЧтениеXML от ПостроителяDOM?
ЧтениеXML обрабатывает документ последовательно, не загружая его целиком в память — подходит для файлов любого размера, но не позволяет вернуться к пройденным узлам. ПостроительDOM строит полное дерево документа в памяти, давая свободную навигацию, ценой расхода памяти пропорционального размеру файла.
Как прочитать XML из строки, а не из файла?
Используйте метод УстановитьСтроку(СтрокаXML) вместо ОткрытьФайл(). Это удобно при получении XML из HTTP-запроса, веб-сервиса или поля базы данных.
Почему русский текст из XML читается нечитаемыми символами?
Кодировка файла не совпадает с той, в которой его открывает платформа. Укажите кодировку явно вторым параметром метода ОткрытьФайл, например КодировкаТекста.ANSI для windows-1251, либо пересохраните файл в UTF-8.
Как получить значение атрибута элемента?
На узле с типом НачалоЭлемента вызовите Чтение.ПолучитьАтрибут("ИмяАтрибута"). Метод возвращает строку или Неопределено, если атрибута нет — проверяйте результат перед использованием.
Что делать, если структура XML заранее неизвестна?
Используйте потоковое чтение с выводом имени и типа каждого узла в отладочный лог — так вы восстановите реальную структуру документа. Альтернатива — открыть файл в браузере или редакторе с подсветкой XML и изучить иерархию визуально.
Что важно запомнить
По умолчанию разбирайте XML через ЧтениеXML — это безопасно по памяти и достаточно для большинства задач. DOM берите для сложной навигации по небольшим файлам, XDTO — при наличии схемы и регулярном обмене. Всегда закрывайте чтение, преобразовывайте строки в нужные типы и ищите объекты базы по надёжным ключам, а не по наименованию.