К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как распарсить XML в 1С: практическое руководство

Как распарсить XML в 1С: потоковое чтение через ЧтениеXML, работа с XDTO-пакетами, DOM-модель, обработка ошибок и проверка результата с примерами кода.

XML — основной формат обмена данными в экосистеме 1С: через него выгружаются документы, справочники, ответы веб-сервисов, файлы ЭДО и выгрузки из сторонних систем. Задача «распарсить XML» возникает у разработчика и у внедренца регулярно: загрузить прайс поставщика, разобрать ответ банка, прочитать файл обмена между базами.

В платформе 1С есть три принципиально разных подхода к разбору XML: потоковое чтение через объект ЧтениеXML, объектная модель XDTO и DOM-парсер (ЧтениеDOM). Выбор зависит от размера файла, наличия схемы и того, что нужно сделать с данными — просто прочитать несколько полей или полностью отобразить структуру на объекты конфигурации.

Ниже разобраны все три способа с рабочими примерами кода, критериями выбора и типичными ошибками, которые приводят к потере данных или падению обработки на больших файлах.

Какие способы разбора XML есть в платформе 1С

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

СпособКак работаетКогда применятьОграничение
ЧтениеXMLПотоковое последовательное чтение узловБольшие файлы, простая структура, загрузка по частямНет произвольного доступа к узлам, только вперёд
ФабрикаXDTOОтображение XML на объекты по схеме (XSD)Форматы со схемой: обмены EnterpriseData, ЭДО, веб-сервисыТребуется пакет XDTO, иначе типы будут нестрогими
ЧтениеDOMЗагрузка всего документа в дерево в памятиСложная навигация, повторный доступ к узлам, XPathВесь файл в памяти — риск на больших файлах

Дополнительно существует объект ЧтениеFastInfoset для бинарного варианта XML, но в повседневной практике он встречается редко. Для типовой задачи «прочитать файл и создать документы» почти всегда достаточно ЧтениеXML.

Маршрут решения

Как выбрать способ разбора

Файл больше нескольких десятков мегабайт или размер неизвестенИспользуйте потоковое ЧтениеXML — только оно не загружает файл целиком в память
Есть XSD-схема формата (обмен между конфигурациями, ЭДО, СБИС, веб-сервис)Читайте через ФабрикаXDTO.ПрочитатьXML с указанием пакета
Нужно многократно обращаться к разным веткам дерева или искать по XPathЗагрузите документ через ЧтениеDOM и работайте с узлами
Структура простая: список однотипных элементов с атрибутамиДостаточно ЧтениеXML с циклом и проверкой типа узла

Потоковый разбор через ЧтениеXML

Объект ЧтениеXML читает документ последовательно, узел за узлом, не загружая файл целиком. Это самый экономичный по памяти способ и стандарт де-факто для загрузки выгрузок.

Базовый шаблон выглядит так: создать объект, открыть файл, в цикле вызывать Прочитать() и анализировать ТипУзла и Имя. Когда встретился нужный элемент — читать его атрибуты и текст.

Чтение = Новый ЧтениеXML;

Чтение.ОткрытьФайл("C:\Обмен\Товары.xml");

Пока Чтение.Прочитать() Цикл

Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента

И Чтение.Имя = "Товар" Тогда

Артикул = Чтение.ПолучитьАтрибут("Артикул");

Наименование = "";

// читаем вложенные элементы товара

Пока Чтение.Прочитать() Цикл

Если Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента

И Чтение.Имя = "Товар" Тогда

Прервать;

КонецЕсли;

Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента

И Чтение.Имя = "Наименование" Тогда

Чтение.Прочитать();

Наименование = Чтение.Значение;

КонецЕсли;

КонецЦикла;

СоздатьЭлементСправочника(Артикул, Наименование);

КонецЕсли;

КонецЦикла;

Чтение.Закрыть();

Ключевые моменты шаблона: вложенный цикл обязательно завершается по КонецЭлемента с тем же именем, иначе позиция чтения «уедет» и структура разберётся неверно. Атрибуты доступны только когда текущий узел — начало элемента; после перехода к тексту они уже недоступны.

Для чтения XML из строки (например, ответа HTTP-запроса) вместо ОткрытьФайл() используется УстановитьСтроку(ТекстXML). Остальной код не меняется.

Разбор через фабрику XDTO

XDTO (XML Data Transfer Objects) — механизм, который отображает XML на типизированные объекты по схеме. Если формат описан XSD-схемой (а это все штатные форматы обмена 1С, EnterpriseData, форматы ЭДО), XDTO избавляет от ручного обхода узлов: вы читаете файл одной командой и получаете объект со свойствами.

Чтение = Новый ЧтениеXML;

Чтение.ОткрытьФайл("C:\Обмен\Сообщение.xml");

ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(Чтение);

Для Каждого СтрокаТовара Из ОбъектXDTO.Товары.Строка Цикл

Сообщить(СтрокаТовара.Наименование + " — " + СтрокаТовара.Количество);

КонецЦикла;

Если схема не подключена к конфигурации, фабрика прочитает документ как нестрогую структуру: все значения будут строками, а обращение к несуществующему свойству вызовет ошибку. Поэтому перед обращением к необязательным полям проверяйте их наличие через ОбъектXDTO.Свойства().Получить("ИмяПоля") или используйте Установлено().

Для типовых обменов пакеты XDTO обычно уже есть в конфигурации (ветка «XDTO-пакеты» в дереве конфигурации). Указать конкретный пакет при чтении можно через параметр типа: ФабрикаXDTO.ПрочитатьXML(Чтение, ТипПакета).

DOM-парсер и навигация по дереву

ЧтениеDOM строит в памяти полное дерево документа, по которому можно свободно перемещаться: обращаться к дочерним узлам, родителям, искать элементы по имени. Это удобно, когда структура сложная и данные из разных веток нужны одновременно.

Чтение = Новый ЧтениеXML;

Чтение.ОткрытьФайл("C:\Обмен\Заказы.xml");

Построитель = Новый ПостроительDOM;

Документ = Построитель.Прочитать(Чтение);

Заказы = Документ.ПолучитьЭлементыПоИмени("Заказ");

Для Каждого УзелЗаказа Из Заказы Цикл

Номер = УзелЗаказа.ПолучитьАтрибут("Номер");

Для Каждого Дочерний Из УзелЗаказа.ДочерниеУзлы Цикл

Если Дочерний.ИмяУзла = "Сумма" Тогда

Сумма = Дочерний.ТекстовоеСодержимое;

КонецЕсли;

КонецЦикла;

КонецЦикла;

DOM оправдан, когда нужен многократный доступ к узлам в произвольном порядке или поиск по всему документу через ПолучитьЭлементыПоИмени(). Платой за удобство является расход памяти: дерево целиком хранится в оперативной памяти, поэтому для потоковой загрузки больших выгрузок DOM не подходит.

Чтение XML из строки и из HTTP-ответа

Частый сценарий — разобрать XML, полученный от веб-сервиса или API, без сохранения в файл. Для этого ЧтениеXML имеет метод УстановитьСтроку().

HTTPЗапрос = Новый HTTPЗапрос("/api/orders");

HTTPСоединение = Новый HTTPСоединение("server.example.com");

Ответ = HTTPСоединение.Получить(HTTPЗапрос);

Если Ответ.КодСостояния = 200 Тогда

Чтение = Новый ЧтениеXML;

Чтение.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());

// далее обычный цикл разбора

КонецЕсли;

Обратите внимание на кодировку: если сервис отдаёт XML в UTF-8, а строка прочитана в другой кодировке, русские символы превратятся в «кракозябры» ещё до парсинга. Метод ПолучитьТелоКакСтроку() обычно определяет кодировку из заголовков, но при сомнениях укажите её явно.

Порядок действий при загрузке XML в 1С
  1. 1
    Получите образец файла и изучите его структуру в текстовом редакторе: имена элементов, атрибуты, вложенность
  2. 2
    Определите, есть ли XSD-схема; если есть — подключите пакет XDTO, если нет — планируйте разбор через ЧтениеXML
  3. 3
    Напишите разбор в тестовой обработке и выведите результат в таблицу значений без записи в базу
  4. 4
    Сверьте распознанные данные с источником: количество строк, ключевые суммы, несколько случайных позиций
  5. 5
    Добавьте запись в базу с транзакцией, поиском существующих элементов и протоколированием ошибок
  6. 6
    Выполните загрузку на копии рабочей базы, проверьте результат и только потом запускайте в рабочей

Обработка ошибок и типичные проблемы

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

Основные правила устойчивого парсинга: оборачивайте разбор в попытку/исключение с записью номера строки файла, преобразуйте типы через явные функции с проверкой, никогда не предполагайте, что необязательный элемент присутствует.

Функция СтрокаВЧисло(Знач Значение)

Значение = СтрЗаменить(СокрЛП(Значение), ",", ".");

Попытка

Возврат Число(Значение);

Исключение

Возврат 0;

КонецПопытки;

КонецФункции

Типичные ошибки
01
Чтение атрибута после перехода к тексту элемента — атрибуты доступны только на узле НачалоЭлемента, иначе получите Неопределено
02
Вложенный цикл без проверки КонецЭлемента — позиция чтения смещается, и остаток файла разбирается неправильно
03
Запись каждого элемента в отдельной транзакции при загрузке тысяч объектов — скорость падает в десятки раз; группируйте запись порциями
04
Игнорирование пространств имён: элемент <ns:Товар> не найдётся по имени «Товар» без учёта URI пространства
05
Чтение огромного файла через XDTO или DOM — нехватка памяти и аварийное завершение сеанса
06
Отсутствие поиска существующих элементов перед созданием — дубли справочников при повторной загрузке

Проверка результата разбора

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

Контрольные точки

Как проверить результат

Количество загруженных объектов
Норма

Совпадает с количеством элементов в файле (или отличается на известное число отклонённых)

Тревожный признак

Загружено меньше — часть данных потеряна без сообщений об ошибках

Ключевые поля (артикул, номер, ИНН)
Норма

Во всех записях заполнены и соответствуют источнику

Тревожный признак

Есть пустые значения или «кракозябры» — проблема с кодировкой или структурой

Итоговые суммы и количества
Норма

Сводные итоги по загруженным данным равны итогам источника

Тревожный признак

Расхождения — ошибка преобразования типов или пропуск вложенных элементов

Повторная загрузка того же файла
Норма

Новых дублей не создаётся, данные обновляются

Тревожный признак

Каждый запуск плодит дубли — не реализован поиск существующих элементов

Полезно вести протокол загрузки: сколько элементов прочитано, сколько создано, сколько обновлено, сколько пропущено с указанием причин. Без протокола разбор расхождений через неделю после загрузки превращается в гадание.

Итог

Что важно запомнить

Для большинства задач используйте потоковое ЧтениеXML с циклом по узлам; при наличии XSD-схемы — фабрику XDTO; для сложной навигации — DOM. Всегда проверяйте результат на тестовой копии, преобразуйте типы явно, ведите протокол и защищайтесь от дублей поиском существующих элементов.

Частые вопросы о разборе XML в 1С

Чем ЧтениеXML отличается от XDTO простыми словами?

ЧтениеXML — это ручной обход файла узел за узлом: вы сами решаете, что делать с каждым элементом. XDTO — автоматическое отображение файла на готовый объект со свойствами по схеме. Первый способ универсальнее и экономнее по памяти, второй удобнее при наличии схемы и сложной типизированной структуре.

Как прочитать XML, если в нём используются пространства имён?

У ЧтениеXML сравнивайте не только свойство Имя, но и URIПространстваИмен, либо используйте свойство ЛокальноеИмя, если пространство не важно. В DOM метод ПолучитьЭлементыПоИмени имеет перегрузку с указанием URI пространства имён.

Файл весит несколько гигабайт — как его разобрать?

Только потоковым ЧтениеXML: он читает файл порциями и не загружает его в память. XDTO и DOM в этом случае не подойдут. Дополнительно записывайте объекты в базу пакетами с фиксацией транзакции каждые несколько тысяч записей, чтобы не наращивать длинную транзакцию.

Почему русские буквы из XML отображаются нечитаемыми?

Причина почти всегда в несовпадении кодировки: файл сохранён в UTF-8, а читается как windows-1251, или наоборот. Проверьте кодировку в объявлении XML (<?xml version="1.0" encoding="..."?>) и задайте её явно при открытии файла или чтении тела HTTP-ответа.

Можно ли распарсить XML без написания кода?

Для штатных форматов обмена между конфигурациями 1С есть типовые обработки «Универсальный обмен данными в формате XML» и обмен через EnterpriseData — они разбирают файлы без программирования. Для произвольного XML стороннего формата код писать придётся, либо используйте готовые обработки загрузки под конкретный формат.

Как безопасно отладить обработку загрузки?

Разделите обработку на два этапа: сначала разбор XML в таблицу значений с выводом на экран, затем запись в базу. Первый этап безопасен полностью. Запись тестируйте на копии базы, включайте режим транзакции с возможностью отката и добавьте флаг «тестовый режим», который выполняет все проверки, но не фиксирует изменения.