При открытии обработки загружаем необходимую компоненту v7plus.dll и создаём объект XMLParser. После загрузки файла в анализатор, создаём выборку основного узла документа "Файл" и последовательно считываем подчиненные элементы, разворачивая их процедурой с рекурсией. Во время чтения узлов можно делать параллельную обработку их значений и компоновать данные в объекты формы, для дальнейшего использования. Если узел не является текстом, то процедура создаёт для него структуру в виде таблицы значений, у которой всегда будут колонки "имя" [строка], "атрибуты" [список значений] и "значение" [текст/структура]
Во время обработки узлов можно получать данные для синхронизации с текущими объектами базы данных, и находить соответствующие объекты, подразумеваемые в файле обмена. Таким образом можно автоматизировать подбор товаров, поиск контрагента и его подчиненных объектов.
Зачем это нужно? В связи с распространением ЭДО появилась возможность быстро передавать данные, однако в большинстве случаев оказывается, что у разных организаций одни и те же объекты (товары, контрагенты и т.д) имеют различное представление, разные коды, разные наименования, и вообще, всё что можно сделать разным - разное. Данная обработка позволяет автоматизировать процесс превращения текстовых данных в объекты программы, находить их не только по уникальным кодам, но и по любым другим признакам, которые может передавать партнер в документе. Можно группировать различные виды дополнительной информации в один вид, подходящий для вашей организации. Без такой автоматизации передача текстовой информации - всё равно, что очки мартышке - ни сколько не облегчает работу сотрудника, т.к. после приёма приходится вручную обрабатывать данные.
//........
//*******************************************
Процедура ОбработкаУзла(ТЗ)
// пример обработки некоторых узлов
Если ТЗ.Имя = "Документ" Тогда
// какие-то движухи по атрибутам узла
ИначеЕсли ТЗ.Имя = "СвСчФакт" Тогда
Если ТипЗначенияСтр(ТЗ.Атрибуты) = "СписокЗначений" Тогда
НомерДок = ТЗ.Атрибуты.Получить("НомерСчФ");
ДатаДок = Дата(ТЗ.Атрибуты.Получить("ДатаСчФ"));
КонецЕсли;
ИначеЕсли ТЗ.Имя = "Продавец" Тогда
ИНН = "";
Если ТипЗначенияСтр(ТЗ.Значение) = "СписокЗначений" Тогда
идСВ = ТЗ.Значение.Получить("ИдСв");
Если ТипЗначенияСтр(идСВ) = "ТаблицаЗначений" Тогда
СвОрг = идСВ.Значение.Получить("СвОрг");
Если ТипЗначенияСтр(СвОрг) = "ТаблицаЗначений" Тогда
СвЮЛ = СвОрг.Значение.Получить("СвЮЛ");
ИНН = СвЮЛ.Атрибуты.Получить("ИННЮЛ");
КонецЕсли;
КонецЕсли;
КонецЕсли;
Сообщить("- ИНН продавца: " + ИНН);
Если ПустаяСтрока(ИНН) = 0 Тогда Продавец = глНайтиПоРеквизиту("Контрагенты","ИНН",ИНН); КонецЕсли;
ИначеЕсли ТЗ.Имя = "СвПрод" Тогда
// ....
ИначеЕсли ТЗ.Имя = "Покупатель" Тогда
// ....
ИначеЕсли ТЗ.Имя = "СвПокуп" Тогда
// ....
ИначеЕсли ТЗ.Имя = "ИдентДок" Тогда
Если ТипЗначенияСтр(ТЗ.Атрибуты) = "СписокЗначений" Тогда
НомерДок = ТЗ.Атрибуты.Получить("НомДокПТ");
ДатаДок = Дата(ТЗ.Атрибуты.Получить("ДатаДокПТ"));
КонецЕсли;
ИначеЕсли (ТЗ.Имя = "СведТов") ИЛИ (ТЗ.Имя = "СвТов") Тогда
// поиск товара
выбТовар = ""; Количество = 0; Ставка = ""; Сумма = "";
Если ТипЗначенияСтр(ТЗ.Атрибуты) = "СписокЗначений" Тогда
Код = ТЗ.Атрибуты.Получить("КодТов");
Наименование = ТЗ.Атрибуты.Получить("НаимТов");
Артикул = ТЗ.Атрибуты.Получить("АртикулТов");
ШК = ТЗ.Атрибуты.Получить("Штрихкод");
Ставка = Число(ТЗ.Атрибуты.Получить("НалСт"));
Если ТЗ.Имя = "СвТов" Тогда
Количество = Число(ТЗ.Атрибуты.Получить("КолМест"));
Сумма = Число(ТЗ.Атрибуты.Получить("СтУчНДС"));
Иначе
Количество = Число(ТЗ.Атрибуты.Получить("КолТов"));
Сумма = Число(ТЗ.Атрибуты.Получить("СтТовУчНал"));
КонецЕсли;
Если (ПустаяСтрока(Код) = 0) ИЛИ (ПустаяСтрока(Наименование) = 0) ИЛИ (ПустаяСтрока(Артикул) = 0) Тогда
выбТовар = НайтиТовар(Код,Наименование,Артикул,ШК);
КонецЕсли;
Сообщить("-- товар: " + ?(ПустоеЗначение(выбТовар) = 1,"не найден",выбТовар));
КонецЕсли;
Если ПустоеЗначение(выбТовар) = 1 Тогда
Если ТипЗначенияСтр(ТЗ.Значение) = "СписокЗначений" Тогда
Код = ""; Наименование = ""; Артикул = ""; ШК = "";
Для Сч = 1 По ТЗ.Значение.РазмерСписка() Цикл
подчВетка = ТЗ.Значение.ПолучитьЗначение(Сч);
подчВетка.ВыбратьСтроки();
Пока подчВетка.ПолучитьСтроку() = 1 Цикл
Ид = ""; Зн = "";
Если подчВетка.Имя = "ИнфПолФХЖ2" Тогда
Если ТипЗначенияСтр(подчВетка.Атрибуты) = "СписокЗначений" Тогда
Ид = подчВетка.Атрибуты.Получить("Идентиф");
Зн = подчВетка.Атрибуты.Получить("Значен");
КонецЕсли;
Если (Нрег(Ид) = "код") ИЛИ (Нрег(Ид) = "ид") ИЛИ (Нрег(Ид) = "кодтов") Тогда Код = Зн КонецЕсли;
Если (Нрег(Ид) = "шк") ИЛИ (Нрег(Ид) = "штрихкод") ИЛИ (Нрег(Ид) = "штрихкодтов") Тогда ШК = Зн КонецЕсли;
Если (Нрег(Ид) = "артикул") ИЛИ (Нрег(Ид) = "арт") ИЛИ (Нрег(Ид) = "артикултов") Тогда Артикул = Зн КонецЕсли;
Если (Нрег(Ид) = "наименование") ИЛИ (Нрег(Ид) = "название") ИЛИ (Нрег(Ид) = "наимтов") Тогда Наименование = Зн КонецЕсли;
ИначеЕсли подчВетка.Имя = "ДопСведТов" Тогда
Если ТипЗначенияСтр(подчВетка.Атрибуты) = "СписокЗначений" Тогда
Если ПустаяСтрока(Наименование) = 1 Тогда Наименование = подчВетка.Атрибуты.Получить("НаимТов"); КонецЕсли;
Если ПустаяСтрока(Артикул) = 1 Тогда Артикул = подчВетка.Атрибуты.Получить("АртикулТов"); КонецЕсли;
Если ПустаяСтрока(Код) = 1 Тогда Код = подчВетка.Атрибуты.Получить("КодТов"); КонецЕсли;
Если ПустаяСтрока(ШК) = 1 Тогда ШК = подчВетка.Атрибуты.Получить("ШтрихкодТов"); КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
выбТовар = НайтиТовар(Код,Наименование,Артикул,ШК);
КонецЕсли;
Сообщить("-- товар: " + ?(ПустоеЗначение(выбТовар) = 1,"не найден",выбТовар));
КонецЕсли;
// ....
Иначе
// ....
КонецЕсли;
КонецПроцедуры
//*******************************************
Функция ПрочитатьПодч(Узел,Уровень=0)
тзВетка = СоздатьОбъект("ТаблицаЗначений");
тзВетка.НоваяКолонка("Имя","Строка",,,,,,);
тзВетка.НоваяКолонка("Значение",,,,,,,);
тзВетка.НоваяКолонка("Атрибуты",,,,,,,);
Если Узел.nodename = "#text" Тогда
// если тип узла обычный текст, то возвращаем его без стуктуры
Возврат Узел.Текст;
Иначе
// узел не является текстом, следовательно у него будет структура таблицы значений, где будет колонка с именем узла, атрибутами и их значениями в виде списка и само значение как ссылка на вложенные объекты
СП = СоздатьОбъект("СписокЗначений");
Для Сч = 1 По Узел.КоличествоАтрибутов() Цикл
УзелАтрибута = Узел.ПолучитьУзелАтрибута(Сч);
СП.ДобавитьЗначение(УзелАтрибута.value,УзелАтрибута.name);
КонецЦикла;
тзВетка.НоваяСтрока();
тзВетка.Имя = Узел.nodename;
тзВетка.Атрибуты = СП;
тзВетка.Значение = СоздатьОбъект("СписокЗначений");
Для Сч = 1 По Узел.КоличествоПодчиненных() Цикл
Подч = Узел.ПолучитьПодчиненныйПоНомеру(Сч);
Если Узел.КоличествоПодчиненных() > 0 Тогда
тзВетка.Значение.Установить(Подч.nodename,ПрочитатьПодч(Подч,Уровень + 1));
КонецЕсли;
КонецЦикла;
ОбработкаУзла(тзВетка);
КонецЕсли;
Возврат тзВетка;
КонецФункции
//*******************************************
Процедура ПрочитатьФайлXML()
XMLАнализатор = СоздатьОбъект("AddIn.XMLParser");
текФайл = XMLАнализатор.СоздатьДокумент();
текФайл.Загрузить(ИмяФайла);
Выборка = текФайл.ВыбратьУзлы("Файл");
Для й = 0 По Выборка.КоличествоУзлов - 1 Цикл
Узел = Выборка.ПолучитьУзел(й);
ПрочитатьПодч(Узел);
КонецЦикла;
КонецПроцедуры
//*******************************************
Процедура ПриОткрытии()
ЗагрузитьВнешнююКомпоненту(КаталогПрограммы() + "v7plus.dll");
// список всех названий узлов в файле
тзТовары.НоваяКолонка("Товар","Справочник.Номенклатура",,,,,,);
тзТовары.НоваяКолонка("Количество","Число",,,,,,);
тзТовары.НоваяКолонка("Сумма","Число",,,,,,);
тзТовары.НоваяКолонка("Цена","Число",,,,,,);
тзТовары.НоваяКолонка("Ставка","Число",,,,,,);
Если ТипЗначенияСтр(Форма.Параметр) = "ГрупповойКонтекст" Тогда
Конт = Форма.Параметр;
КонецЕсли;
КонецПроцедуры