Работа с XML-файлами в 1С:Предприятие — одна из самых востребованных задач при интеграции с внешними системами, обмене данными между базами или обработке отчетности. Однако многие разработчики сталкиваются с трудностями при попытке преобразовать XML-данные в удобную структуру 1С, будь то Структура, Соответствие или ТаблицаЗначений. В этой статье мы разберем все актуальные способы чтения XML, от стандартных механизмов платформы до оптимизированных решений для сложных случаев.
Особенность работы с XML в 1С заключается в том, что платформа предоставляет несколько инструментов для парсинга — от простого ЧтениеXML до мощного XDTO. Выбор метода зависит от структуры исходного файла, требований к производительности и дальнейшей обработке данных. Мы рассмотрим каждый подход на практике, с примерами кода и пояснениями, когда какой способ применять.
Если вы ранее работали только с JSON или текстовymi файлами, XML может показаться избыточно сложным из-за своей иерархической структуры, тегов и атрибутов. Но после прочтения этой статьи вы сможете уверенно обрабатывать даже многогнездовые XML-документы, извлекать нужные данные и преобразовывать их в удобные для 1С форматы.
1. Базовые понятия: что такое XML и как он устроен
XML (eXtensible Markup Language) — это текстовый формат данных, который широко используется для обмена информацией между системами. В отличие от JSON, XML поддерживает атрибуты элементов, пространства имен и более сложную вложенность, что делает его универсальным, но иногда громоздким.
Основные компоненты XML-документа:
- 📌 Элементы (теги) — основные строительные блоки, например,
<Сотрудник>. Могут быть вложенными и содержать другие элементы или текст. - 🔖 Атрибуты — дополнительные свойства элементов, например,
ID="123"в теге<Сотрудник ID="123">. - 📄 Текстовое содержимое — данные внутри тега, например,
<Имя>Иванов</Имя>. - 🔄 Пространства имен — механизм для избежания конфликтов имен тегов (например,
xmlns:ns="http://example.com").
В 1С XML чаще всего встречается в следующих сценариях:
- 📥 Импорт данных из внешних систем (банки, госорганы, партнеры).
- 📤 Экспорт данных для отчетности (например, СЗВ-ТД или ЕГАИС).
- 🔄 Обмен между базами 1С (через Универсальный формат обмена).
- 🛠️ Интеграция с веб-сервисами (SOAP, REST с XML-ответами).
⚠️ Внимание: Если ваш XML-файл содержит пространства имен (атрибутыxmlns), стандартное чтение черезЧтениеXMLможет не сработать корректно. В таких случаях потребуетсяXDTOили ручная обработка.
2. Способ 1: Чтение XML через объект ЧтениеXML
Самый простой и распространенный метод — использование встроенного объекта ЧтениеXML. Он подходит для небольших XML-файлов с простой структурой, где не требуется валидация по схеме или работа с пространствами имен.
Основные этапы работы:
- Создать объект
ЧтениеXML. - Открыть файл или строку с XML-данными.
- Последовательно читать узлы (элементы, атрибуты, текст).
- Записывать данные в структуру 1С (например,
СтруктураилиТаблицаЗначений).
Пример кода для чтения простого XML в структуру:
Процедура ПрочитатьXMLВСтруктуру(ПутьКФайлу)
Чтение = Новый ЧтениеXML();
Чтение.ОткрытьФайл(ПутьКФайлу);
Результат = Новый Структура();
Пока Чтение.Прочитать() Цикл
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
ИмяТега = Чтение.Имя;
Если Чтение.Пустой Тогда
Результат.Вставить(ИмяТега, Неопределено);
ИначеЕсли Чтение.Атрибуты.Количество() > 0 Тогда
Атрибуты = Новый Структура();
Для Каждого Атр Из Чтение.Атрибуты Цикл
Атрибуты.Вставить(Атр.Имя, Атр.Значение);
КонецЦикла;
Результат.Вставить(ИмяТега, Атрибуты);
КонецЕсли;
ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.Текст Тогда
Результат.Вставить(Чтение.Имя, Чтение.Значение);
КонецЕсли;
КонецЦикла;
Чтение.Закрыть();
Возврат Результат;
КонецПроцедуры
Этот код обрабатывает XML вида:
<Данные>
<Имя>Иванов</Имя>
<Возраст>30</Возраст>
<Адрес Город="Москва" Улица="Ленина" />
</Данные>
⚠️ Внимание: ОбъектЧтениеXMLне поддерживает автоматическую валидацию по XSD-схеме. Если структура XML должна строго соответствовать заданному формату, используйтеXDTO(см. раздел 4).
3. Способ 2: Преобразование XML в ТаблицуЗначений
Если данные в XML имеют табличную структуру (например, список товаров, сотрудников или документов), удобнее сразу преобразовать их в ТаблицуЗначений. Это позволит дальше работать с данными как с обычной таблицей: фильтровать, сортировать, группировать.
Алгоритм преобразования:
- Определить структуру целевой таблицы (колонки и их типы).
- Читать XML построчно, заполняя строки таблицы.
- Обрабатывать вложенные элементы как отдельные колонки или связанные таблицы.
Пример кода для XML со списком товаров:
Функция XMLВТаблицуЗначений(ПутьКФайлу)
Чтение = Новый ЧтениеXML();
Чтение.ОткрытьФайл(ПутьКФайлу);
Таблица = Новый ТаблицаЗначений();
Таблица.Колонки.Добавить("Наименование", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("Цена", Новый ОписаниеТипов("Число"));
Таблица.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
ТекущаяСтрока = Таблица.Добавить();
Пока Чтение.Прочитать() Цикл
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
Если Чтение.Имя = "Товар" Тогда
ТекущаяСтрока = Таблица.Добавить();
ИначеЕсли Чтение.Имя = "Наименование" Тогда
Чтение.Прочитать(); // Переходим к текстовому узлу
ТекущаяСтрока.Наименование = Чтение.Значение;
ИначеЕсли Чтение.Имя = "Цена" Тогда
Чтение.Прочитать();
ТекущаяСтрока.Цена = Число(Чтение.Значение);
ИначеЕсли Чтение.Имя = "Количество" Тогда
Чтение.Прочитать();
ТекущаяСтрока.Количество = Число(Чтение.Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Чтение.Закрыть();
Возврат Таблица;
КонецФункции
Для XML вида:
<Товары>
<Товар>
<Наименование>Монитор</Наименование>
<Цена>15000</Цена>
<Количество>5</Количество>
</Товар>
<Товар>
<Наименование>Клавиатура</Наименование>
<Цена>2000</Цена>
<Количество>10</Количество>
</Товар>
</Товары>
Определить структуру целевой таблицы (колонки и типы)|Проверить XML на наличие обязательных полей|Учесть вложенные элементы (нужны ли отдельные таблицы)|Обработать возможные ошибки чтения (try-catch)-->
4. Способ 3: Использование XDTO для сложных XML
XDTO (XML Data Transfer Objects) — это механизм платформы 1С:Предприятие, предназначенный для работы со сложными XML-структурами, включая:
- 🔗 XML с пространствами имен (
xmlns). - 📋 XML, соответствующий XSD-схемам (валидация).
- 🔄 Сериализация/десериализация объектов 1С в XML.
Преимущества XDTO перед ЧтениеXML:
| Критерий | ЧтениеXML | XDTO |
|---|---|---|
| Поддержка пространств имен | ❌ Нет | ✅ Да |
| Валидация по XSD | ❌ Нет | ✅ Да |
| Скорость обработки | ⚡ Быстрее для простых XML | 🐢 Медленнее, но гибче |
| Удобство для сложных структур | ❌ Трудночитаемый код | ✅ Объектная модель |
Пример использования XDTO для чтения XML с пространством имен:
Процедура ПрочитатьXMLСXDTO(ПутьКФайлу)
// 1. Загружаем XDTO-пакет (если есть схема)
ФабрикаXDTO = Новый ФабрикаXDTO();
ФабрикаXDTO.ПространстваИмен.Добавить("http://example.com/ns", "Префикс");
// 2. Чтение XML
ЧтениеXML = Новый ЧтениеXML();
ЧтениеXML.ОткрытьФайл(ПутьКФайлу);
// 3. Десериализация в объект XDTO
ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
// 4. Преобразование в структуру 1С
Результат = Новый Структура();
Результат.Вставить("Данные", ОбъектXDTO.Значение);
ЧтениеXML.Закрыть();
Возврат Результат;
КонецПроцедуры
XDTO обязателен, если XML содержит атрибуты xmlns или требуется валидация по схеме. Без XDTO такие файлы будут читаться некорректно или вовсе не обработаются.
Когда без XDTO не обойтись?
Если XML содержит пространства имен (xmlns), например:
<ns:Документ xmlns:ns="http://example.com">,
или требуется проверка соответствия XSD-схеме, то ЧтениеXML не подойдет.
XDTO также удобен, когда нужно сериализовать объекты 1С обратно в XML с сохранением структуры.
5. Способ 4: Чтение XML через Запрос (XMLЧтение)
Малоизвестный, но мощный способ — использование объекта Запрос с методом XMLЧтение. Этот подход позволяет читать XML как поток данных и сразу загружать его в временные таблицы для дальнейшей обработки SQL-подобными запросами.
Преимущества метода:
- 🚀 Высокая скорость обработки больших XML-файлов.
- 🔧 Возможность использовать
Запросдля фильтрации и преобразования данных. - 📊 Удобно для дальнейшего анализа данных через СКД.
Пример кода:
Процедура ПрочитатьXMLЧерезЗапрос(ПутьКФайлу)
ТекстXML = Новый ЧтениеТекста(ПутьКФайлу);
Текст = ТекстXML.ПрочитатьВсюСтроку();
ТекстXML.Закрыть();
Запрос = Новый Запрос();
Запрос.Текст =
"ВЫБРАТЬ
| XMLДанные.Значение КАК Наименование,
| XMLДанные.Атрибуты.Цена КАК Цена
|ИЗ
| &XMLЧтение("" + Текст + "", ""Товары/Товар"") КАК XMLДанные";
РезультатЗапроса = Запрос.Выполнить();
ТаблицаРезультата = РезультатЗапроса.Выгрузить();
// Дальнейшая обработка ТаблицаРезультата
КонецПроцедуры
Этот метод особенно полезен, когда нужно:
- 📊 Обработать большой XML-файл (например, выгрузку из ЕГАИС или ФНС).
- 🔍 Отфильтровать данные прямо при чтении (например, выбрать товары с ценой > 1000).
- 🔄 Преобразовать XML в таблицу для отчета.
⚠️ Внимание: Метод XMLЧтение в запросах поддерживается только в 1С:Предприятие 8.3.10 и выше. В более ранних версиях этот способ не работает.
6. Обработка ошибок и типичные проблемы
При чтении XML в 1С часто возникают ошибки, связанные с:
- 🔤 Некорректной кодировкой (например,
UTF-8vsWindows-1251). - 📉 Несоответствием структуры (отсутствуют ожидаемые теги).
- 🔢 Неверными типами данных (например, текст вместо числа).
- 🔗 Сложными пространствами имен (без XDTO).
Как обработать ошибки:
1. Проверка кодировки:
Попытка
ЧтениеXML.ОткрытьФайл(ПутьКФайлу, КодировкаТекста.UTF8);
Исключение
Сообщить("Ошибка открытия файла: " + ОписаниеОшибки());
ПопробоватьКодировкуWindows1251();
КонецПопытки;
2. Проверка структуры XML:
Если Не ЧтениеXML.Прочитать() Тогда
ВызватьИсключение "XML-файл пуст или имеет неверную структуру";
КонецЕсли;
3. Обработка типов данных:
Попытка
ТекущаяСтрока.Цена = Число(ЧтениеXML.Значение);
Исключение
ТекущаяСтрока.Цена = 0; // Значение по умолчанию
КонецПопытки;
4. Логирование ошибок:
Всегда ведите журнал ошибок чтения XML, особенно если обработка происходит в фоновом задании. Пример:
Процедура ЗаписатьОшибку(Сообщение, Подробности = "")
Журнал = Новый ТекстовыйДокумент();
Журнал.ДобавитьСтроку(ТекущаяДата() + ": " + Сообщение);
Если Подробности <> "" Тогда
Журнал.ДобавитьСтроку("Подробности: " + Подробности);
КонецЕсли;
Журнал.Записать("C:\Logs\XMLErrors.log", КодировкаТекста.UTF8, Истина);
КонецПроцедуры
Если XML содержит специальные символы (например, <, &), используйте функцию РазобратьСтрокуXML() для их корректной обработки.
7. Оптимизация производительности
При работе с большими XML-файлами (например, выгрузками из ЕГАИС или ФНС на тысячи строк) важно оптимизировать процесс чтения, чтобы избежать зависаний 1С. Основные рекомендации:
1. Чтение потоками:
Не загружайте весь XML в память сразу. Читайте файл построчно:
Чтение = Новый ЧтениеXML();
Чтение.ОткрытьФайл(ПутьКФайлу);
Пока Чтение.Прочитать() Цикл
// Обработка текущего узла
КонецЦикла;
2. Использование временных таблиц:
Если данные нужно further обработать, загружайте их во ВременнуюТаблицу вместо обычной ТаблицыЗначений:
Таблица = Новый ТаблицаЗначений();
Таблица.Временная = Истина;
3. Отключение транзакций:
Если чтение XML происходит в цикле с записью в базу, отключите автоматические транзакции:
НачатьТранзакцию();
Попытка
// Чтение и обработка XML
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ЗаписатьОшибку(ОписаниеОшибки());
КонецПопытки;
4. Кэширование XSD-схем:
Если используете XDTO с валидацией по XSD, кэшируйте загруженные схемы:
ФабрикаXDTO = Новый ФабрикаXDTO();
Если Не ФабрикаXDTO.ПространстваИмен.Содержит("http://example.com") Тогда
ФабрикаXDTO.ПространстваИмен.Добавить("http://example.com", Новый XDTOПакет("ПутьКXSD"));
КонецЕсли;
| Метод оптимизации | Когда применять | Эффект |
|---|---|---|
| Построчное чтение | XML > 10 МБ | ↓ Память, ↑ Скорость |
| Временные таблицы | Дальнейшая обработка данных | ↓ Нагрузка на базу |
| Отключение транзакций | Массовая запись в базу | ↑ Производительность |
| Кэширование XSD | Многократное чтение одинаковых XML | ↑ Скорость инициализации |
Для XML-файлов размером более 50 МБ рассмотрите возможность использования внешних утилит (например, Saxon или Python-скриптов) для предварительной обработки.
8. Практический пример: чтение XML выгрузки из банка
Рассмотрим реальный пример: обработка XML-выгрузки банковских платежей (формат 1С:Банк-Клиент). Структура XML может выглядеть так:
<Документ>
<Платежи>
<Платеж Дата="2023-10-15" Сумма="10000">
<Получатель>ООО Ромашка</Получатель>
<ИНН>1234567890</ИНН>
<Назначение>Оплата по договору №123</Назначение>
</Платеж>
<Платеж Дата="2023-10-16" Сумма="5000">
<Получатель>ИП Иванов</Получатель>
<ИНН>0987654321</ИНН>
<Назначение>Аванс</Назначение>
</Платеж>
</Платежи>
</Документ>
Код для чтения в ТаблицуЗначений:
Функция ПрочитатьПлатежиИзXML(ПутьКФайлу)
Чтение = Новый ЧтениеXML();
Чтение.ОткрытьФайл(ПутьКФайлу);
ТаблицаПлатежей = Новый ТаблицаЗначений();
ТаблицаПлатежей.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата"));
ТаблицаПлатежей.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
ТаблицаПлатежей.Колонки.Добавить("Получатель", Новый ОписаниеТипов("Строка"));
ТаблицаПлатежей.Колонки.Добавить("ИНН", Новый ОписаниеТипов("Строка"));
ТаблицаПлатежей.Колонки.Добавить("Назначение", Новый ОписаниеТипов("Строка"));
ТекущийПлатеж = Неопределено;
Пока Чтение.Прочитать() Цикл
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
Если Чтение.Имя = "Платеж" Тогда
ТекущийПлатеж = ТаблицаПлатежей.Добавить();
ТекущийПлатеж.Дата = Чтение.Атрибуты.Получить("Дата");
ТекущийПлатеж.Сумма = Чтение.Атрибуты.Получить("Сумма");
ИначеЕсли ТекущийПлатеж <> Неопределено Тогда
Если Чтение.Имя = "Получатель" Тогда
Чтение.Прочитать();
ТекущийПлатеж.Получатель = Чтение.Значение;
ИначеЕсли Чтение.Имя = "ИНН" Тогда
Чтение.Прочитать();
ТекущийПлатеж.ИНН = Чтение.Значение;
ИначеЕсли Чтение.Имя = "Назначение" Тогда
Чтение.Прочитать();
ТекущийПлатеж.Назначение = Чтение.Значение;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Чтение.Закрыть();
Возврат ТаблицаПлатежей;
КонецФункции
Этот код:
- 📅 Читает атрибуты
ДатаиСуммапрямо из тега<Платеж>. - 📝 Извлекает вложенные элементы (
Получатель,ИНН,Назначение). - 📊 Формирует таблицу, готовую для дальнейшей обработки (например, загрузки в документ Поступление безналичных ДС).
Как обработать платежи с одинаковым ИНН?
Если в таблице нужно сгруппировать платежи по ИНН, добавьте после чтения XML следующий код:
Запрос = Новый Запрос();
Запрос.Текст =
"ВЫБРАТЬ
| ИНН,
| СУММА(Сумма) КАК Итого
|ИЗ
| &ТаблицаПлатежей КАК Платежи
|ГРУППИРОВКА ПО
| ИНН";
Результат = Запрос.Выполнить().Выгрузить();
FAQ: Частые вопросы по чтению XML в 1С
🔹 Как прочитать XML из строки, а не из файла?
Используйте метод УстановитьСтроку() вместо ОткрытьФайл():
ЧтениеXML = Новый ЧтениеXML();
ЧтениеXML.УстановитьСтроку(<ВашаXMLСтрока>);
Это удобно, если XML приходит как ответ от веб-сервиса или из другого источника в виде строки.
🔹 Можно ли прочитать XML с помощью XDTO без XSD-схемы?
Да, но функциональность будет ограничена. Пример:
ФабрикаXDTO = Новый ФабрикаXDTO();
ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML, Ложь); // Второй параметр - не использовать схему
В этом случае вы получите "плоскую" структуру без валидации и типизации.
🔹 Как обработать XML с пространствами имен без XDTO?
Можно вручную удалить пространства имен из XML перед чтением:
ТекстXML = Новый ЧтениеТекста(ПутьКФайлу);
Текст = ТекстXML.ПрочитатьВсюСтроку();
Текст = СтрЗаменить(Текст, "xmlns=""http://example.com""", ""); // Удаляем пространство имен
Текст = СтрЗаменить(Текст, "ns:", ""); // Удаляем префиксы
⚠️ Осторожно: Это может сломать структуру XML, если пространства имен критичны.
🔹 Почему при чтении XML возникает ошибка "Неверный формат потока"?
Частые причины:
- 🔤 Неверная кодировка файла (попробуйте
UTF-8илиWindows-1251). - 📉 Файл поврежден или не является корректным XML.
- 🔒 Файл заблокирован другим процессом.
Решение: проверьте файл в любом XML-валидаторе (например, Notepad++ с плагином XML Tools).