Как правильно прочитать имя тега и значение элемента XML в 1С

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

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

Выясним причину ошибки при чтении через ЧтениеXML

В процессе последовательного чтения файла объект ЧтениеXML проходит несколько разных типов узлов для каждого элемента:

  1. НачалоЭлемента: На этом шаге свойство ЧтениеXML.Имя (или ЧтениеXML.ЛокальноеИмя) содержит имя тега (например, Номер). Однако само текстовое значение элемента на данном этапе еще недоступно.
  2. ПрочитатьАтрибут(): Если внутри блока начального элемента вызван цикл перебора атрибутов, то при каждом вызове свойства Имя и Значение перезаписываются данными текущего атрибута (например, xsi:type="xs:string"). По окончании цикла контекст узла оказывается сдвинут.
  3. Текст: Когда курсор перемещается на сам текст внутри тега, свойство ЧтениеXML.ТипУзла принимает значение ТипУзлаXML.Текст. При этом свойство Имя становится пустым, а содержимое тега (например, 00000006435) попадает в свойство ЧтениеXML.Значение.

Попытка проверить условие Если ЧтениеXML.Значение = "Номер" в блоке типа Текст ошибочна, так как Значение хранит строку 00000006435, а имя элемента было доступно только на этапе НачалоЭлемента.

Способ 1. Потоковое чтение с сохранением текущего имени узла

Рассмотрим правильный подход к написанию цикла с использованием ЧтениеXML. Чтобы связать имя тега с его значением, необходимо запоминать имя элемента в отдельную переменную в момент обработки начального узла.

Посмотрим на пример кода:


ТекущееИмяТега = "";

Пока ЧтениеXML.Прочитать() Цикл 

    Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда 
        
        // Запоминаем имя элемента до обработки его атрибутов или содержимого
        ТекущееИмяТега = ЧтениеXML.ЛокальноеИмя; 
        
    ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда 
        
        // Сравниваем сохраненное имя элемента с искомым
        Если ТекущееИмяТега = "Номер" Тогда
            СтрокаНомер = ЧтениеXML.Значение;
        ИначеЕсли ТекущееИмяТега = "Дата" Тогда
            СтрокаДата = ЧтениеXML.Значение;
        КонецЕсли;
        
    ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда 
        
        // Сбрасываем имя при закрытии тега
        ТекущееИмяТега = "";
        
    КонецЕсли; 

КонецЦикла;

Если требуется получить значение конкретного атрибута (например, тип данных), лучше использовать метод ПолучитьАтрибут("type") вместо полного цикла ПрочитатьАтрибут(), чтобы не сбивать указатель текущего узла.

Способ 2. Автоматическая десериализация через ПрочитатьXML()

Если файл был сформирован с использованием метода ЗаписатьXML с явным указанием типов (когда в XML присутствуют атрибуты xsi:type), платформе 1С не требуется ручной разбор типа данных. Для чтения таких узлов предназначен встроенный метод ПрочитатьXML().

Разберем по шагам, как это работает:

  1. Позиционируем ЧтениеXML на нужный начальный элемент.
  2. Передаем объект чтения в функцию ПрочитатьXML().

Проанализируем пример кода:


Пока ЧтениеXML.Прочитать() Цикл 
    
    Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента И ЧтениеXML.ЛокальноеИмя = "Номер" Тогда
        // Метод считывает значение тега и автоматически приводит его к типу 1С
        ЗначениеНомера = ПрочитатьXML(ЧтениеXML); 
    КонецЕсли;
    
КонецЦикла;

Способ 3. Чтение документа через Фабрику XDTO

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

Рассмотрим пример использования:


// Чтение XML-файла в объект XDTO
ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);

// Доступ к значению тега "Номер" напрямую по имени
ЗначениеНомера = ОбъектXDTO.Номер;

Важное замечание: Чтение через ФабрикуXDTO или ПостроительDOM загружает весь файл в оперативную память. Для работы с файлами большого объема (сотни мегабайт) рекомендуется использовать потоковый разбор через ЧтениеXML с явным сохранением имени тега (Способ 1).

← На главную