Приветствую Вас ГостьСреда, 16.07.2025, 11:32

Каталог статей


Чтение XML файла средствами 1С

https://infostart.ru/public/311011/

http://scientes.tmweb.ru/32/?commentId=47


Читать XML файл в лоб часто не удобно. Чтобы было удобнее обрабатывать данные XML можно воспользоваться Xpath.

Правда есть один недостаток: быстродействие... Этот метод хорош для небольших файлов со сложной структурой.

Для примера рассмотрим файл XML:

<?xml version="1.0" encoding="UTF-8"?>
<Данные>
    <Объекты>
        <Объект Имя="УчасткиГазопроводов">
            <Параметры>
                <Параметр ИмяПараметра="ВГ_КодУчастка" Наименование="В г код участка" ТипЗначения="Строка(50)"/>
                <Параметр ИмяПараметра="ГлубинаПрокладки" Наименование="Глубина прокладки, м" ТипЗначения="Число(10.2)"/>
                <Параметр ИмяПараметра="ГлубинаПрокладкиМаксимум" Наименование="Глубина прокладки максимум" ТипЗначения="Число(10.2)"/>
                <Параметр ИмяПараметра="ГлубинаПрокладкиМинимум" Наименование="Глубина прокладки, м" ТипЗначения="Число(10.2)"/>
                <Параметр Имя="ГрунтКоррозионнаяАгрессивность" Наименование="Коррозионная агрессивность грунта" ТипЗначения="Ссылка.ВыдыКоррозионнойАгрессивностиГрунта"/>
                 <Параметр Имя="ГрунтМетодЗащитыОтКоррозии" Наименование="Грунт метод защиты от коррозии" ТипЗначения="Ссылка.МетодыЗащитыОтКоррозии"/>
            </Параметры>
        </Объект>
    </Объекты>
    <ЗначенияСсылочныхТипов>
        <Ссылка.ВыдыКоррозионнойАгрессивностиГрунта Иерархический="false">
            <Значения>
                <ЗначениеПараметра Значение="высокая" Родитель="" ЭтоГруппа="false"/>
                <ЗначениеПараметра Значение="низкая" Родитель="" ЭтоГруппа="false"/>
                <ЗначениеПараметра Значение="средняя" Родитель="" ЭтоГруппа="false"/>
            </Значения>
        </Ссылка.ВыдыКоррозионнойАгрессивностиГрунта>
        <Ссылка.МетодыЗащитыОтКоррозии Иерархический="true">
            <Значения>
                <ЗначениеПараметра Значение="пассивная" Родитель="" ЭтоГруппа="true"/>
                <ЗначениеПараметра Значение="электрохимическая" Родитель="" ЭтоГруппа="true"/>
                <ЗначениеПараметра Значение="не требуется" Родитель="" ЭтоГруппа="false"/>
                <ЗначениеПараметра Значение="Электрохимическая" Родитель="" ЭтоГруппа="false"/>
                <ЗначениеПараметра Значение="дренажная" Родитель="электрохимическая" ЭтоГруппа="false"/>
                <ЗначениеПараметра Значение="катодная" Родитель="электрохимическая" ЭтоГруппа="false"/>
                <ЗначениеПараметра Значение="протекторная" Родитель="электрохимическая" ЭтоГруппа="false"/>
                <ЗначениеПараметра Значение="весьма усиленная изоляция" Родитель="пассивная" ЭтоГруппа="false"/>
                <ЗначениеПараметра Значение="лакокрасочное покрытие" Родитель="пассивная" ЭтоГруппа="false"/>
                <ЗначениеПараметра Значение="экструдированный полиэтилен" Родитель="пассивная" ЭтоГруппа="false"/>
            </Значения>
        </Ссылка.МетодыЗащитыОтКоррозии>
    </ЗначенияСсылочныхТипов>
</Данные>

Надо получить перечень "Объекты" и его "Параметры", а потом перечень "ЗначенияСсылочныхТипов". Получать данные будем с помощью запросов:

  • "/Данные/Объекты/Объект" - чтобы получить список объектов.
  • "/Данные/ЗначенияСсылочныхТипов" - чтобы получить значения ссылочных типов

Пример кода:

    ДОМ=новый ПостроительDOM;
    ЧтениеXML=Новый ЧтениеXML;
    ЧтениеXML.ОткрытьФайл(ИмяФайлаXML);
    ДокументДОМ=ДОМ.Прочитать(ЧтениеXML);        
    РазыменовательПИ=ДокументДОМ.СоздатьРазыменовательПИ(ДокументДОМ);    
    
    ЗапросXML="/Данные/Объекты/Объект";    
    Путь=ДокументДОМ.СоздатьВыражениеXPath(ЗапросXML,РазыменовательПИ);
    РезультатВыборки = Путь.Вычислить(ДокументДОМ);    

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

    ВыборкаОбъект=РезультатВыборки.ПолучитьСледующий();
    Пока ВыборкаОбъект<>неопределено Цикл    
        ...
        ВыборкаОбъект=РезультатВыборки.ПолучитьСледующий();
    КонецЦикла;

В переменную ВыборкаОбъект помещается значение типа ЭлементDOM. 

Получить имя узла: ВыборкаОбъект.ИмяУзла (в нашем примере "Объект")

Получит значение атрибута по имени: ИмяПараметра= ВыборкаОбъект.Атрибуты.ПолучитьИменованныйЭлемент("ИмяПараметра").ТекстовоеСодержимое;

Перебрать коллекцию дочерних узлов: Для каждого ДочернийУзел ИЗ ВыборкаОбъект.ДочерниеУзлы Цикл ... КонецЦикла;

Получить значение булево значение атрибута: ЭтоГруппа = XMLЗначение(Тип("Булево"), ЗначениеПараметра.Атрибуты.ПолучитьИменованныйЭлемент("ЭтоГруппа").ТекстовоеСодержимое);

Пока не обнулили значение ДокументДОМ, можно выполнять различные запросы к загруженному документу XML.

Чтобы была такая возможность и не писать каждый раз повторяющийся код, текст кода был разбит на 2 процедуры.

Первое обращение:

&НаСервере
Функция ПолучитьВыборкуПоЗапросуXpath(Знач ДокументДОМ, Знач ЗапросXML, Знач РазыменовательПИ)    
    Перем Путь;                                                                                   
    Путь=ДокументДОМ.СоздатьВыражениеXPath(ЗапросXML,РазыменовательПИ);
    Возврат Путь.Вычислить(ДокументДОМ);                                                      
КонецФункции

Процедура...

    РезультатВыборки = Неопределено;   
    ДокументДОМ = Неопределено;
    РазыменовательПИ = Неопределено;
    ЗапросXML="/Данные/Объекты/Объект";
    СформироватьРезультатВыборкиXML(ИмяФайлаПараметров, ЗапросXML, РезультатВыборки, ДокументДОМ, РазыменовательПИ);

    ВыборкаОбъект=РезультатВыборки.ПолучитьСледующий();
    Пока ВыборкаОбъект<>неопределено Цикл
        ...       
        ВыборкаОбъект=РезультатВыборки.ПолучитьСледующий();
    КонецЦикла;
 

Второе обращение

    ЗапросXML = "/Данные/ЗначенияСсылочныхТипов";
    РезультатВыборки = ПолучитьВыборкуПоЗапросуXpath(ДокументДОМ, ЗапросXML, РазыменовательПИ);
    ВыборкаЗначения=РезультатВыборки.ПолучитьСледующий();
    

ДокументДОМ, РазыменовательПИ сохраняем, чтобы была возможность неоднократно обращаться к загруженному XML документу.


Если верить статье в первой ссылке, то методы использующие DOM работают очень медленно. Более быстрый способ - использовать ФабрикаXDTO.

Есть и минус - проблемы с определением списка. Список - это последовательность элементов одного с одинаковым именем элементов. Если в списке всего один элемент, то ФабрикаXDTO посчитает его свойством, поэтому требуется делать проверку. Обращаться к атрибутам можно через точку, как к свойствам объекта.

Пример на том же файле XML:

    ЧтениеXML=Новый ЧтениеXML ;
    ЧтениеXML.ОткрытьФайл(ИмяФайлаПараметров);
    ДанныеXML = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
    
    Если ТипЗнч(ДанныеXML.Объекты.Объект) <> Тип("СписокXDTO") Тогда
        СписокОбъектовВДГО = Новый Массив();
        СписокОбъектовВДГО = СписокОбъектовВДГО.Добавить(ДанныеXML.Объекты.Объект);
    Иначе
        СписокОбъектовВДГО = ДанныеXML.Объекты.Объект;
    КонецЕсли;

        
    Для каждого ОбъектВДГО из СписокОбъектовВДГО Цикл
        
        ИмяОбъектаВДГО = ОбъектВДГО.Имя;
        ...        
    КонецЦикла;
    
    Если ТипЗнч(ДанныеXML.ЗначенияСсылочныхТипов.СсылочныйТип) <> Тип("СписокXDTO") Тогда
        СписокСсылочныхТипов = Новый Массив();
        СписокСсылочныхТипов.Добавить(ДанныеXML.ЗначенияСсылочныхТипов.СсылочныйТип);
    Иначе
        СписокСсылочныхТипов = ДанныеXML.ЗначенияСсылочныхТипов.СсылочныйТип;
    КонецЕсли;
    
    Для каждого СсылочныйТип из СписокСсылочныхТипов Цикл
        ...
    КонецЦикла;

 

Категория: Взаимодействие с другими базами, приложениями и источниками данных | Добавил: leshic (15.10.2019)
Просмотров: 504 | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Код *:
Вход на сайт
Поиск
Категории раздела
СКД [51]
Регистры [7]
Формы [47]
Администрирование [48]
Запросы [11]
Объекты конфигурации и типы данных [20]
Взаимодействие с другими базами, приложениями и источниками данных [16]
Программирование [47]
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0