Открываем XML в 1С: от текстового просмотра до дерева значений
Содержание
Прочитать XML глазами можно в Конфигураторе, браузере или любом текстовом редакторе. Разобрать его программно, чтобы получить значения в таблицу или дерево, в 1С 8.3 можно встроенным объектом ЧтениеXML. Готовой кнопки «Открыть XML
» в обычной форме 1С нет: файл либо смотрят как текст, либо читают кодом, либо загружают обработкой обмена.
Какой путь выбрать, зависит от задачи. Нужно один раз посмотреть, что внутри выгрузки, хватит текста. Нужно регулярно забирать данные из файла контрагента, пишите обработку. Нужно загрузить файл, который сформировала сама 1С, берите обработку обмена данными.
Что за файл у вас в руках
Перед выбором способа выясните три вещи.
- 📄 Откуда файл. Выгрузка из 1С в формате обмена, ответ банка или маркетплейса, файл от контрагента, служебный XML ЭДО. От источника зависит, чем его открывать.
- 📏 Размер. До нескольких мегабайт спокойно открывается любым способом. Файл на сотни мегабайт текстовый документ 1С загрузит целиком в память, а
ЧтениеXMLчитает потоком. - 🔤 Кодировка. В первой строке файла обычно стоит
<?xml version="1.0" encoding="UTF-8"?>илиencoding="windows-1251". Запомните её, она понадобится дальше.
Если файл пришёл по почте, скопируйте его в обычную папку на диске. Читать из вложения письма или из архива неудобно, а у части программ не хватает прав на запись рядом.
Просмотр без программирования
Это самый быстрый вариант, когда нужно понять структуру.
Конфигуратор
Запустите базу в режиме Конфигуратора, выберите Файл → Открыть и укажите XML. Файл откроется как текстовый документ с нумерацией строк и поиском по Ctrl+F. Минус: Конфигуратор занимает лицензионный сеанс, а структура не подсвечивается как дерево.
Браузер и редактор
Перетащите файл в Chrome, Edge или Firefox. Браузер покажет узлы деревом со сворачиванием, а если в файле синтаксическая ошибка, сообщит, в какой строке. Для больших файлов и поиска по тегам удобнее Notepad++ или VS Code с плагином форматирования.
Что даёт такой просмотр
| Способ | Подходит, когда | Ограничение |
|---|---|---|
| Конфигуратор | Нужно быстро взглянуть из 1С | Нет дерева, только текст |
| Браузер | Проверить корректность и структуру | Не передаёт данные в 1С |
| Текстовый редактор | Большой файл, поиск, правка | Данные в 1С не попадают |
ЧтениеXML в обработке | Нужны значения в таблице | Нужен код |
Читаем XML кодом через ЧтениеXML
Объект ЧтениеXML идёт по файлу последовательно, узел за узлом. Метод Прочитать() переходит к следующему узлу и возвращает Ложь, когда файл закончился. Тип текущего узла лежит в свойстве ТипУзла: ТипУзлаXML.НачалоЭлемента, ТипУзлаXML.КонецЭлемента, ТипУзлаXML.Текст.
Минимальный пример: вывести в сообщения все элементы с их значениями.
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл("C:\Temp\data.xml");
Пока Чтение.Прочитать() Цикл
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
Сообщить("Элемент: " + Чтение.Имя);
ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.Текст Тогда
Сообщить(" Значение: " + Чтение.Значение);
КонецЕсли;
КонецЦикла;
Чтение.Закрыть();
Атрибуты читают, пока курсор стоит на начале элемента:
Для Индекс = 0 По Чтение.КоличествоАтрибутов() - 1 Цикл
Сообщить(Чтение.ИмяАтрибута(Индекс) + " = " + Чтение.ЗначениеАтрибута(Индекс));
КонецЦикла;
Если нужен атрибут по имени, используйте Чтение.ПолучитьАтрибут("Имя"): вернёт значение или пустую строку.
Закрывайте чтение методом Закрыть(). Пока файл открыт, Windows не даст его удалить или перезаписать, а на сервере залипший дескриптор потом мешает чистке временных каталогов.
Когда лучше DOM
Для небольших файлов, где нужно прыгать по структуре вперёд и назад, подойдёт ПостроительDOM. Он читает весь документ в память и отдаёт дерево объектов:
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл("C:\Temp\data.xml");
Построитель = Новый ПостроительDOM;
Документ = Построитель.Прочитать(Чтение);
Чтение.Закрыть();
Корень = Документ.ДокументЭлемент;
Сообщить("Корневой элемент: " + Корень.ИмяУзла);
Дальше узлы обходят через Корень.ДочерниеУзлы. На больших файлах этот путь съедает много памяти, там берите потоковое чтение.
Выводим XML в дерево значений
Структура XML вложенная, и естественный приёмник для неё — ДеревоЗначений. Заведите в обработке реквизит с типом «ДеревоЗначений» и колонки Элемент, Атрибуты, Значение. Затем заполните его так:
&НаСервере
Процедура ЗагрузитьВДерево(ИмяФайла, Дерево)
Дерево.Строки.Очистить();
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ИмяФайла);
Текущая = Неопределено;
Пока Чтение.Прочитать() Цикл
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
Если Текущая = Неопределено Тогда
Новая = Дерево.Строки.Добавить();
Иначе
Новая = Текущая.Строки.Добавить();
КонецЕсли;
Новая.Элемент = Чтение.Имя;
Новая.Значение = "";
Новая.Атрибуты = "";
Для Индекс = 0 По Чтение.КоличествоАтрибутов() - 1 Цикл
Новая.Атрибуты = Новая.Атрибуты + Чтение.ИмяАтрибута(Индекс)
+ "=" + Чтение.ЗначениеАтрибута(Индекс) + "; ";
КонецЦикла;
Текущая = Новая;
ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.Текст Тогда
Если Текущая <> Неопределено Тогда
Текущая.Значение = Текущая.Значение + СокрЛП(Чтение.Значение);
КонецЕсли;
ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
Если Текущая <> Неопределено Тогда
Текущая = Текущая.Родитель;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Чтение.Закрыть();
КонецПроцедуры
Логика простая. На открывающем теге создаём строку на нужном уровне и делаем её текущей. На тексте дописываем значение в текущую строку. На закрывающем теге поднимаемся к родителю. Свойство Родитель у строки верхнего уровня возвращает Неопределено, поэтому цикл корректно выходит из корня.
На форме выведите реквизит как таблицу, у которой в свойствах включено отображение иерархии. Получится раскрываемое дерево, похожее на то, что показывает браузер, но уже внутри 1С и с возможностью выгрузить его в табличный документ.
Если в XML много однотипных записей (тысячи строк документов), дерево на форме будет тормозить. Тогда сразу складывайте данные в ТаблицаЗначений по нужным тегам, а не отражайте всю структуру.
Загрузка через обработку обмена данными
Если XML сформировала сама 1С (выгрузка по правилам обмена, перенос справочников между базами), писать разбор вручную не нужно. Для таких файлов есть штатная обработка универсального обмена данными в формате XML: она читает файл вместе с правилами и создаёт объекты в базе. Открывается она из Файл → Открыть, если лежит в виде внешней обработки .epf, или из раздела администрирования, если поставляется в составе вашей конфигурации. Точное место зависит от конфигурации, поэтому ищите её по слову «обмен» в меню Администрирование.
Для произвольного XML из чужой системы эта обработка не годится. Она ждёт строго свою структуру. В остальных случаях выбирайте между кодом и расширением:
- 🔹 Структура простая и стабильная: достаточно
ЧтениеXMLи разбора по именам тегов. - 🔹 Файл описан схемой XSD и сложный: используйте сериализацию через XDTO, платформа сама превратит XML в объекты.
- 🔹 Нужна загрузка в справочник или документ: прочитайте данные в таблицу значений, покажите пользователю для проверки и только после этого записывайте элементы.
Пользовательскую обработку можно подключить как внешнюю: Файл → Открыть, выбрать .epf. Для постоянного использования добавьте её в справочник «Дополнительные отчёты и обработки», если он включён в вашей конфигурации.
Кодировки и спецсимволы
Большая часть «странностей» при чтении XML сводится к двум причинам.
Кодировка
ЧтениеXML.ОткрытьФайл() смотрит на объявление в первой строке и читает файл в заявленной кодировке. Проблемы начинаются, когда объявление врёт: файл сохранили в windows-1251, а в заголовке стоит UTF-8. На экране вместо слов появляются последовательности вроде Привет.
Что делать:
- Откройте файл в Notepad++ и посмотрите кодировку в статусной строке.
- Пересохраните в нужной кодировке и поправьте объявление в первой строке.
- Если исправить источник нельзя, читайте файл как текст с явной кодировкой и подавайте строку в
ЧтениеXMLметодомУстановитьСтроку().
Текст = Новый ТекстовыйДокумент;
Текст.Прочитать("C:\Temp\data.xml", КодировкаТекста.ANSI);
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(Текст.ПолучитьТекст());
Здесь ANSI соответствует windows-1251 в русской Windows. Если объявление внутри строки всё ещё называет другую кодировку, замените его на подходящее до разбора.
Отдельный случай — BOM, служебные байты в начале файла UTF-8. Платформа с ними справляется, а вот самодельная правка файла строковыми функциями иногда ломает первую строку.
Спецсимволы
В XML пять символов записываются сущностями:
| Символ | Запись |
|---|---|
& | & |
< | < |
> | > |
" | " |
' | ' |
ЧтениеXML превращает их обратно сам, и в Чтение.Значение вы получите обычный амперсанд или скобку. Заменять сущности вручную не нужно, иначе получите двойное преобразование. Блоки <![CDATA[ ... ]]> читаются как обычный текст, внутри них сущности не раскрываются.
Управляющие символы с кодами меньше 32 (кроме табуляции, перевода строки и возврата каретки) в XML недопустимы. Если в данных попался, например, символ из вставки текста из Excel, чтение остановится с исключением. Такие символы удаляют до записи файла на стороне источника.
Если файл не открывается
Оберните чтение в Попытка и покажите причину пользователю:
Попытка
Чтение.ОткрытьФайл(ИмяФайла);
// разбор
Исключение
Сообщить("Не удалось прочитать XML: " + ОписаниеОшибки());
КонецПопытки;
Типовые причины, от простых к редким:
- ❌ Файл не найден. Путь указан на клиенте, а код выполняется на сервере. Серверная процедура не видит диск вашего компьютера. Передайте файл через хранилище значения или положите в папку, доступную серверу.
- ❌ Документ оборван. Файл скачался не полностью, и закрывающих тегов нет. Откройте в браузере: он покажет, где разбор остановился.
- ❌ Несколько корневых элементов. В корректном XML корень один. Если кто-то склеил два файла подряд, разберите их отдельно.
- ❌ Недопустимый символ в данных, см. выше.
- ❌ Лишний текст перед
<?xml. Пробел или строка перед объявлением делает документ невалидным. Удалите всё, что стоит до угловой скобки.
Частые вопросы
Можно ли открыть XML в 1С обычным двойным щелчком?
Чем отличается ЧтениеXML от ПостроительDOM?
ЧтениеXML идёт потоком и почти не занимает память. ПостроительDOM загружает документ целиком и даёт произвольный доступ к узлам. Для файлов в десятки мегабайт берут первое.Как прочитать только один нужный тег?
НачалоЭлемента с нужным именем, затем прочитайте следующий узел типа Текст. Дальше можно выйти из цикла и закрыть чтение.