Разработка и Конфигурация · 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
Объект Чтение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, а строка прочитана в другой кодировке, русские символы превратятся в «кракозябры» ещё до парсинга. Метод ПолучитьТелоКакСтроку() обычно определяет кодировку из заголовков, но при сомнениях укажите её явно.
- 1Получите образец файла и изучите его структуру в текстовом редакторе: имена элементов, атрибуты, вложенность
- 2Определите, есть ли XSD-схема; если есть — подключите пакет XDTO, если нет — планируйте разбор через ЧтениеXML
- 3Напишите разбор в тестовой обработке и выведите результат в таблицу значений без записи в базу
- 4Сверьте распознанные данные с источником: количество строк, ключевые суммы, несколько случайных позиций
- 5Добавьте запись в базу с транзакцией, поиском существующих элементов и протоколированием ошибок
- 6Выполните загрузку на копии рабочей базы, проверьте результат и только потом запускайте в рабочей
Обработка ошибок и типичные проблемы
Реальные XML-файлы редко бывают идеальными. Пустые теги, отсутствующие атрибуты, числа с запятой вместо точки, даты в неожиданном формате — всё это нужно обрабатывать явно, иначе загрузка упадёт на середине или, что хуже, запишет искажённые данные.
Основные правила устойчивого парсинга: оборачивайте разбор в попытку/исключение с записью номера строки файла, преобразуйте типы через явные функции с проверкой, никогда не предполагайте, что необязательный элемент присутствует.
Функция СтрокаВЧисло(Знач Значение)
Значение = СтрЗаменить(СокрЛП(Значение), ",", ".");
Попытка
Возврат Число(Значение);
Исключение
Возврат 0;
КонецПопытки;
КонецФункции
Проверка результата разбора
После загрузки обязательно сверьте результат с источником. Минимальный набор контрольных точек: количество обработанных элементов, контрольные суммы (итоговая сумма документов, общее количество товаров), отсутствие записей с пустыми ключевыми полями.
Как проверить результат
Совпадает с количеством элементов в файле (или отличается на известное число отклонённых)
Загружено меньше — часть данных потеряна без сообщений об ошибках
Во всех записях заполнены и соответствуют источнику
Есть пустые значения или «кракозябры» — проблема с кодировкой или структурой
Сводные итоги по загруженным данным равны итогам источника
Расхождения — ошибка преобразования типов или пропуск вложенных элементов
Новых дублей не создаётся, данные обновляются
Каждый запуск плодит дубли — не реализован поиск существующих элементов
Полезно вести протокол загрузки: сколько элементов прочитано, сколько создано, сколько обновлено, сколько пропущено с указанием причин. Без протокола разбор расхождений через неделю после загрузки превращается в гадание.
Что важно запомнить
Для большинства задач используйте потоковое Чтение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 в таблицу значений с выводом на экран, затем запись в базу. Первый этап безопасен полностью. Запись тестируйте на копии базы, включайте режим транзакции с возможностью отката и добавьте флаг «тестовый режим», который выполняет все проверки, но не фиксирует изменения.