Чтение XML файла с помощью XMLParser

Чтение XML файла с помощью XMLParser

Пример кода чтения XML файла с обработкой значений.
Автоматизация загрузки ЭДО УПД

При открытии обработки загружаем необходимую компоненту 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");
	// список всех названий узлов в файле
 	тзТовары.НоваяКолонка("Товар","Справочник.Номенклатура",,,,,,);
 	тзТовары.НоваяКолонка("Количество","Число",,,,,,);
 	тзТовары.НоваяКолонка("Сумма","Число",,,,,,);
 	тзТовары.НоваяКолонка("Цена","Число",,,,,,);
 	тзТовары.НоваяКолонка("Ставка","Число",,,,,,);
 	Если ТипЗначенияСтр(Форма.Параметр) = "ГрупповойКонтекст" Тогда
 		Конт = Форма.Параметр;
 	КонецЕсли;
КонецПроцедуры

Типы узлов, NodeType

  • 1 — узел элемента;
  • 2 — узел атрибута;
  • 3 — текстовый узел;
  • 4 — узел секции CDATA;
  • 5 — узел ссылки на сущность (Entity Reference);
  • 6 — узел сущности (Entity);
  • 7 — узел инструкции обработки;
  • 8 — узел комментария;
  • 9 — узел документа;
  • 10 — узел описания типа документа (DTD);
  • 11 — узел фрагмента документа;
  • 12 — узел объявления XML (XML Declaration).

Вход



Регистрация