Чтение XML-файла в 1С 8.3: от просмотра до кода
Содержание
XML-файл нельзя «открыть в 1С» одной кнопкой так, чтобы данные сами легли в справочник или документ. Платформа умеет читать XML только кодом или через готовую обработку загрузки. Зато посмотреть содержимое можно за минуту, а прочитать программно — несколькими способами, от простого к экономному по памяти.
Ниже — пять рабочих подходов в 1С 8.3: просмотр без программирования, потоковый ЧтениеXML, ПостроительDOM, XDTO и обработка файлов на сотни мегабайт. В конце — типичные ошибки, из-за которых чтение падает или отдаёт пустоту.
С чего начать: что за XML перед вами
Сначала выясните, откуда файл. От этого зависит способ.
| Источник файла | Что с ним делать |
|---|---|
| Выгрузка из другой программы 1С или обмен по правилам | Загрузка штатным механизмом обмена, свой код не нужен |
| Электронный документ (счёт-фактура, УПД, накладная) | Открывается через ЭДО, а не парсится вручную |
| Банковская или торговая выгрузка в собственном формате | Свой разбор: ЧтениеXML или ПостроительDOM |
Файл с описанием схемы (.xsd) | Подключается к XDTO как пакет |
Откройте файл в обычном текстовом редакторе и посмотрите первые строки. Там есть кодировка и корневой элемент:
<?xml version="1.0" encoding="UTF-8"?>
<Данные>
<Товар Код="00012">
<Наименование>Гвозди 50 мм</Наименование>
<Цена>12.50</Цена>
</Товар>
</Данные>
Если вместо кириллицы видны «кракозябры», дело в кодировке. Файл часто сохранён в windows-1251, а в заголовке написано UTF-8 (или наоборот). Это ломает чтение — подробнее в последнем разделе.
Посмотреть содержимое файла без программирования
Если нужно только увидеть данные, код писать не надо.
- Перетащите файл в браузер или откройте его в текстовом редакторе. Браузер сворачивает дерево элементов — удобно для больших файлов.
- В Конфигураторе откройте файл через меню
Файл → Открыть. Он покажется как текст. - В обычном тексте найдите нужный элемент поиском по имени тега.
Для разовой задачи этого хватает: нашли значение, скопировали, ввели вручную.
Не открывайте XML-выгрузку банка или ЭДО в Конфигураторе боевой базы только ради просмотра. Достаточно любого редактора на рабочем месте. Конфигуратор нужен, когда вы пишете код.
Чтобы поймать файл из пользовательского режима, нужна внешняя обработка или готовая загрузка. Её открывают через Файл → Открыть в обычном клиенте, если разрешено открытие внешних файлов. Это уже ближе к разработке.
Потоковое чтение: ЧтениеXML
ЧтениеXML идёт по файлу последовательно, как курсор. Он не держит в памяти всё дерево. Это основной инструмент, когда структура простая или файл большой.
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл("C:\Обмен\goods.xml");
Пока Чтение.Прочитать() Цикл
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента И Чтение.Имя = "Товар" Тогда
Код = Чтение.ЗначениеАтрибута("Код");
Сообщить("Товар с кодом " + Код);
КонецЕсли;
КонецЦикла;
Чтение.Закрыть();
Метод Прочитать() переходит к следующему узлу и возвращает Ложь в конце файла. Тип текущего узла лежит в ТипУзла. Самые нужные значения:
- 📌
НачалоЭлемента— открывающий тег, имя вИмяилиЛокальноеИмя; - 📌
Текст— содержимое между тегами, значение вЗначение; - 📌
КонецЭлемента— закрывающий тег.
Чтобы получить текст внутри элемента, после начала элемента сделайте ещё один Прочитать() и проверьте, что узел — Текст:
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента И Чтение.Имя = "Наименование" Тогда
Чтение.Прочитать();
Если Чтение.ТипУзла = ТипУзлаXML.Текст Тогда
Наименование = Чтение.Значение;
КонецЕсли;
КонецЕсли;
Пустой элемент <Цена/> текстового узла не даёт. Если не проверить тип, получите значение следующего тега.
Атрибуты читаются по имени: ЗначениеАтрибута("Код"). Перебрать все можно циклом по КоличествоАтрибутов() с ИмяАтрибута(Индекс) и ЗначениеАтрибута(Индекс).
Всегда закрывайте чтение через Закрыть(). Иначе файл остаётся занятым, и следующая запись или удаление упадёт с ошибкой доступа.
Открыть XML из строки, а не из файла
Не всегда данные лежат на диске. Они приходят из веб-сервиса, из реквизита или из двоичных данных. Для таких случаев у ЧтениеXML есть метод УстановитьСтроку.
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(ТекстXML);
Чтение.ПерейтиКСодержимому();
ПерейтиКСодержимому() сразу ставит курсор на первый содержательный узел и пропускает объявление <?xml ...?>. Удобно, когда вы передаёте поток дальше в XDTO или ПостроительDOM.
Ещё два свойства стоит знать:
- ⚙️
ИгнорироватьПробелы— отбрасывает пробельные узлы между тегами. Без него в красиво отформатированном файле между элементами появляются лишние текстовые узлы с переводами строк, и цикл «сам себя путает»; - ⚙️
ПолучитьСтрокууЗаписьXML— обратная операция, когда результат нужно вернуть строкой.
Пример. Файл с отступами и тремя товарами без ИгнорироватьПробелы даст в цикле не три, а около семи узлов-кандидатов: по каждому товару добавятся пробельные тексты. Если вы проверяете ТипУзла и имя, это не страшно. Если считаете «каждый второй узел — товар», получите ошибку.
Дерево в памяти: ПостроительDOM
ПостроительDOM читает весь документ и собирает дерево. По нему можно ходить в любом порядке, искать узлы по имени и возвращаться назад. Платите за это памятью.
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл("C:\Обмен\goods.xml");
Построитель = Новый ПостроительDOM;
Документ = Построитель.Прочитать(Чтение);
Чтение.Закрыть();
Товары = Документ.ПолучитьЭлементыПоИмени("Товар");
Для Каждого Товар Из Товары Цикл
Код = Товар.ПолучитьАтрибут("Код");
Для Каждого Дочерний Из Товар.ДочерниеУзлы Цикл
Если Дочерний.ИмяУзла = "Наименование" Тогда
Сообщить(Код + ": " + Дочерний.ТекстовоеСодержимое);
КонецЕсли;
КонецЦикла;
КонецЦикла;
Когда брать DOM:
- ✅ файл небольшой — единицы мегабайт;
- ✅ нужны данные из разных частей документа одновременно;
- ✅ структура вложенная, порядок элементов не гарантирован.
Для обхода дочерних элементов удобнее перебирать ДочерниеУзлы и сверять имя. Текст лежит в ТекстовоеСодержимое.
Пример расчёта объёма: файл в 20 МБ в виде DOM занимает в памяти заметно больше исходного размера, потому что каждый узел — отдельный объект. На клиенте с ограничением по памяти это упрётся быстрее, чем кажется. Для файлов больше десятка мегабайт переходите на потоковое чтение.
XDTO: когда у файла есть схема
XDTO превращает XML в объекты 1С и обратно по описанной схеме. Если у формата есть .xsd, это самый аккуратный путь: платформа сама проверяет структуру и типы.
Базовый вариант — чтение в объект ОбъектXDTO:
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл("C:\Обмен\order.xml");
Чтение.ПерейтиКСодержимому();
Тип = ФабрикаXDTO.Тип("http://example.org/orders", "Order");
Заказ = ФабрикаXDTO.ПрочитатьXML(Чтение, Тип);
Чтение.Закрыть();
Номер = Заказ.Number;
Здесь http://example.org/orders и Order — условные значения. Подставьте пространство имён и имя типа из вашей схемы. Пакет схемы должен быть подключён к фабрике: в конфигурации он лежит в ветке Общие → Пакеты XDTO.
Плюсы и минусы подхода:
| Плюс | Минус |
|---|---|
| Типы приводятся сами, даты и числа не нужно разбирать вручную | Нужна схема, без неё XDTO бесполезен |
| Структура проверяется при чтении | Несоответствие схеме — сразу исключение |
| К свойствам обращаются через точку | Для разовой простой задачи избыточно |
Если нужно просто сохранить значение 1С в XML и вернуть обратно, пригодится СериализаторXDTO. Он записывает справочники, структуры и массивы в стандартном виде, но читает только то, что записано им же или совместимо с форматом платформы.
Большие файлы: читать кусками, а не целиком
Файл на сотни мегабайт целиком в DOM не загрузить. Тут выручает потоковое чтение с обработкой по порциям.
Рабочая схема:
- Читаете поток через
ЧтениеXML, пока не встретите начало нужного повторяющегося элемента (например,Товар). - Для этого одного элемента читаете его содержимое — вручную или через
ПрочитатьXMLфабрикиXDTO. - Записываете результат в базу и переходите к следующему.
- Каждые несколько тысяч записей фиксируете транзакцию, а не одну на весь файл.
Метод Пропустить() пропускает текущий элемент вместе с содержимым. Он нужен, когда часть файла вам не интересна — например, служебный блок в начале.
Пока Чтение.Прочитать() Цикл
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
Если Чтение.Имя = "Служебное" Тогда
Чтение.Пропустить();
ИначеЕсли Чтение.Имя = "Товар" Тогда
ЗагрузитьТовар(Чтение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Для очень больших загрузок запускайте обработку на сервере через регламентное или фоновое задание. Клиентский сеанс не держит часовую операцию стабильно, а память сервера обычно больше.
Если файл приходит с клиента, сначала поместите его во временное хранилище или на сервер, а не передавайте весь текст строкой в серверный вызов.
Превращаем текст XML в числа, даты и ссылки
Всё, что вы читаете из XML, приходит строкой. 12.50 — это ещё не число, а 2026-10-07T00:00:00 — не дата.
Для преобразования используйте XMLЗначение:
Цена = XMLЗначение(Тип("Число"), "12.50");
Дата = XMLЗначение(Тип("Дата"), "2026-10-07T00:00:00");
Булево = XMLЗначение(Тип("Булево"), "true");
Обратная операция — XMLСтрока(Значение). Она даёт каноничное строковое представление, которое понимает любая система.
Что важно помнить о форматах:
- 🔢 разделитель дробной части в XML — точка, а не запятая как в русской локали;
- 📅 дата записывается в формате
ГГГГ-ММ-ДДTЧЧ:ММ:СС; - ✅ булево —
trueиfalseстрочными; - 🔗 ссылку на элемент справочника из «чужого» XML по строке не получить: ищите её по коду, ИНН или другому реквизиту.
Не используйте Число("12.50") на данных из внешних файлов: результат зависит от региональных настроек и может молча дать ноль.
Для ссылок типовая схема такая: прочитали код из атрибута, нашли элемент Справочники.Номенклатура.НайтиПоКоду(Код), при отсутствии — создали новый или записали в журнал отказов.
Номенклатура = Справочники.Номенклатура.НайтиПоКоду(Код);
Если Номенклатура.Пустая() Тогда
// создаём или пишем в журнал ненайденных
КонецЕсли;
Типичные ошибки при чтении XML
Эти сбои встречаются чаще всего, и почти все лечатся за пять минут.
Кодировка. Заголовок говорит UTF-8, а байты записаны в windows-1251. Результат — непонятные символы или ошибка разбора. Проверьте реальную кодировку в редакторе и при необходимости передайте её явно в ОткрытьФайл(Путь, Кодировка).
Лишние символы в начале. Перед <?xml стоит пробел или перевод строки. Парсер ругается на неверный формат. Уберите всё до объявления.
Файл занят. Забыли Закрыть() у ЧтениеXML. Следующая попытка записи падает. Закрывайте чтение даже при ошибке — через Попытка … Исключение … КонецПопытки.
Пустое значение вместо текста. Не проверили ТипУзла, и вместо текста прочитался закрывающий тег. Всегда сверяйте тип узла после Прочитать().
Пространства имён. В XML элемент называется ns:Товар, а вы ищете Товар. Для поиска по локальному имени используйте ЛокальноеИмя, а не Имя.
Недопустимые символы. Старые выгрузки иногда содержат управляющие символы (код ниже 32, кроме табуляции и переводов строк). XML с ними невалиден. Отфильтруйте их перед разбором.
Несоответствие схеме в XDTO. Объект не создаётся, потому что обязательное поле отсутствует. Сверьте файл с .xsd и сообщение об ошибке — платформа обычно называет проблемный элемент.
Для диагностики удобна обёртка:
Попытка
Чтение.ОткрытьФайл(ПутьКФайлу);
// ... разбор ...
Исключение
ЗаписьЖурналаРегистрации("Загрузка XML", УровеньЖурналаРегистрации.Ошибка,,,
ОписаниеОшибки());
КонецПопытки;
Какой способ выбрать
ПостроительDOM: дерево целиком, ищете узлы по имени.ЧтениеXML в потоке: память не растёт, обработка по записям.XDTO: объекты вместо ручного разбора.СериализаторXDTO, свой разбор не нужен.Частые вопросы
Можно ли открыть XML в 1С без программирования?
Файл → Открыть как текст. Для загрузки данных в справочники нужен код или готовая обработка.Чем `ЧтениеXML` отличается от `ПостроительDOM`?
ЧтениеXML идёт по файлу потоком и почти не занимает память. ПостроительDOM собирает всё дерево и позволяет ходить по нему свободно, но расходует память.Почему число из XML читается как ноль?
XMLЗначение(Тип("Число"), Строка).Как узнать, в какой кодировке файл?
encoding. Если текст читается нормально только в одной, она и настоящая.Нужен ли `XDTO`, если схемы нет?
.xsd проще ЧтениеXML или ПостроительDOM. XDTO окупается там, где формат строго описан.