Как правильно прочитать элементы и атрибуты XML-файла в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции с внешними системами и разборе выгрузок (например, каталогов товаров или прайс-листов) разработчики часто сталкиваются с путаницей в терминологии XML и особенностями работы встроенных объектов 1С. Рассмотрим структуру типового фрагмента XML и разберем, как корректно извлекать значения узлов и их параметров.

Посмотрим на пример структуры XML:


<offer id="20" available="true">
    <url>Адрес_ссылки</url>
    <price>900</price>
    <picture>Ссылка_на_картинку</picture>
    <name>Название_товара</name>
    <param name="Цвет">Зеленый</param>
    <param name="Вес" unit="Кг">3</param>
</offer>

В данном фрагменте важно четко различать два понятия:

  1. Элементы (теги): это узлы разметки, такие как offer, price, name. Текст внутри них (например, 900) является текстовым содержимым элемента (тип узла ТипУзлаXML.Текст).
  2. Атрибуты: это пары «имя=значение», расположенные внутри открывающего тега, например id="20" или name="Цвет".

Способ 1. Потоковое чтение с помощью объекта ЧтениеXML

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

При потоковом чтении мы отслеживаем смену типа узла. Когда курсор попадает на ТипУзлаXML.НачалоЭлемента, мы можем прочитать имя тега и получить его атрибуты. Когда курсор переходит на ТипУзлаXML.Текст, мы считываем строковое значение.

Посмотрим на пример кода разбора предложений в таблицу значений или табличную часть:


ЧтениеXML = Новый ЧтениеXML;
Попытка
    ЧтениеXML.ОткрытьФайл(ПутьКФайлу);
    
    ИмяТекущегоЭлемента = "";
    НоваяСтрока = Неопределено;
    
    Пока ЧтениеXML.Прочитать() Цикл
        
        // 1. Обработка начала элементов и атрибутов
        Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
            
            ИмяТекущегоЭлемента = ЧтениеXML.Имя;
            
            Если ИмяТекущегоЭлемента = "offer" Тогда
                НоваяСтрока = ТаблицаТоваров.Добавить();
                
                // Получаем значение конкретного атрибута напрямую по имени
                НоваяСтрока.ID = ЧтениеXML.ПолучитьАтрибут("id");
                НоваяСтрока.Доступен = ЧтениеXML.ПолучитьАтрибут("available");
            КонецЕсли;
            
        // 2. Обработка текстового содержимого тегов
        ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
            
            Если НоваяСтрока <> Неопределено Тогда
                Если ИмяТекущегоЭлемента = "price" Тогда
                    НоваяСтрока.Цена = Число(ЧтениеXML.Значение);
                ИначеЕсли ИмяТекущегоЭлемента = "name" Тогда
                    НоваяСтрока.Название = ЧтениеXML.Значение;
                ИначеЕсли ИмяТекущегоЭлемента = "url" Тогда
                    НоваяСтрока.Ссылка = ЧтениеXML.Значение;
                КонецЕсли;
            КонецЕсли;
            
        // 3. Обработка закрывающих тегов
        ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
            
            Если ЧтениеXML.Имя = "offer" Тогда
                НоваяСтрока = Неопределено;
            КонецЕсли;
            
            ИмяТекущегоЭлемента = "";
            
        КонецЕсли;
        
    КонецЦикла;
    
Исключение
    Сообщить("Ошибка при чтении XML: " + ОписаниеОшибки());
КонецПопытки;

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

Важные нюансы при потоковом чтении:

  1. Для получения атрибута тега надежнее использовать метод ПолучитьАтрибут("ИмяАтрибута") прямо на узле ТипУзлаXML.НачалоЭлемента, не сдвигая курсор ручным вызовом ПрочитатьАтрибут().
  2. Всегда закрывайте поток через ЧтениеXML.Закрыть() в блоке обработки исключений или после завершения цикла, чтобы файл не оставался заблокированным в операционной системе.

Способ 2. Использование объектной модели DOM (ПостроительDOM)

Если размер XML-документа небольшой (до нескольких десятков мегабайт), удобнее использовать объектную модель ДокументDOM. Это избавляет от необходимости вручную управлять состояниями парсера.

Разберем пример чтения через DOM:


ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлу);

Построитель = Новый ПостроительDOM;
ДокументDOM = Построитель.Прочитать(ЧтениеXML);
ЧтениеXML.Закрыть();

// Получаем все узлы <offer>
СписокОфферов = ДокументDOM.ПолучитьЭлементыПоИмени("offer");

Для Каждого УзелOffer Из СписокОфферов Цикл
    
    НоваяСтрока = ТаблицаТоваров.Добавить();
    
    // Чтение атрибутов
    Если УзелOffer.ЕстьАтрибуты() Тогда
        АтрибутID = УзелOffer.Атрибуты.ПолучитьИменованныйЭлемент("id");
        Если АтрибутID <> Неопределено Тогда
            НоваяСтрока.ID = АтрибутID.ЗначениеУзла;
        КонецЕсли;
    КонецЕсли;
    
    // Чтение дочерних элементов
    Для Каждого ДочернийУзел Из УзелOffer.ДочерниеУзлы Цикл
        Если ДочернийУзел.ТипУзла = ТипУзлаDOM.Элемент Тогда
            Если ДочернийУзел.ИмяУзла = "price" Тогда
                НоваяСтрока.Цена = Число(ДочернийУзел.ТекстовоеСодержимое);
            ИначеЕсли ДочернийУзел.ИмяУзла = "name" Тогда
                НоваяСтрока.Название = ДочернийУзел.ТекстовоеСодержимое;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    
КонецЦикла;

Способ 3. Пакеты XDTO

Для регулярного обмена данными по строгой спецификации наилучшим решением является использование механизма XDTO. С помощью XSD-схемы в конфигурации создается пакет XDTO, после чего файл десериализуется в строго типизированные объекты 1С с помощью ФабрикаXDTO.ПрочитатьXML(). Это полностью исключает ручной парсинг тегов и проверку типов данных.

← На главную