gifts2017

Упрощаем чтение XML или любите СП — источник знаний (2)

Опубликовал Валентин Бомбин (so-quest) в раздел Программирование - Практика программирования

Функция преобразования xml в структуру

 

Однаждый Джоель Мозес (англ. Joel Moses) сказал «APL как красивый бриллиант — безупречный, симметричный. Но вы ничего не можете к нему добавить. Если вы попытаетесь приклеить к нему другой алмаз — вы не получите бóльший алмаз. Лисп же — это ком грязи. Добавь еще и он останется комом грязи — он все еще будет выглядеть как Лисп.» Для меня, кроме лиспа, таким комом грязи стал XML. На протяжении долгого времени на эти значки < и > натягивают все больше и больше семантики. Появляются страшные слова -  DTD,  xsd, xslt, RDF .... Сегодня уже вовсю идет подготовка к Xforms, и кто знает что еще прикрутят к этому формату завтра? Кассанрой работать всегда тяжело, но одно знаю точно — XML останется XML — заголовок и корневой элемент, открывающие и закрывающие тэги, текстовое представление — останется всегда. А раз так — то вечным будет вопрос — как прочитать XML и работать с ним?

Многие пишут свои универсальные функции которые разбирают XML в дерево, в таблицу значений, в массив или как в этой заметке — в структуру. У всех этих способов есть свои плюсы и минусы.

Плюсы подхода изложенного в этой заметке — типизация полученного результата.

Минусы — время работы, объем потребляемой памяти. Поэтому для чтения больших файлов (более 5 kb) слабо подходит.

 

Для примера используется такое определение XSD

 

и вот такой xml для теста

 

Код для преобразования -

 

Функция xdto2struct(XDTO)
	структураОбъекта = новый Структура;
	Для каждого х Из XDTO.свойства() Цикл
		Попытка
			// пусть так определяется что это список. Может и лучше можно, не знаю.
			ПрочитаноеЗначение= XDTO.ПолучитьСписок(х);	
		Исключение
			ПрочитаноеЗначение= XDTO.Получить(х);
		КонецПопытки;
		типЭлемента = типЗнч(ПрочитаноеЗначение);
		если  типЭлемента = тип("ОбъектXDTO") тогда
			структураОбъекта.Вставить(х.Имя,xdto2struct(ПрочитаноеЗначение));
		иначеесли типЭлемента  = тип("СписокXDTO") тогда
			структураОбъекта.Вставить(х.Имя, list2array(ПрочитаноеЗначение));
		иначе
			/// простое значение
			структураОбъекта.Вставить(х.Имя,ПрочитаноеЗначение);
		КонецЕсли;
	КонецЦикла;
	Возврат структураОбъекта;
КонецФункции

функция list2array(listXdto)
	массивВозврата = новый Массив;
	для каждого у из listXdto цикл
		массивВозврата.Добавить(новый Структура("Тип,Значение",ТипВСтруктуру(у.тип()),xdto2struct(у)));
	конецЦикла;
	возврат массивВозврата;
КонецФункции

Функция ТипВСтруктуру(типРазбора)
	Возврат  Новый Структура("URI,имя",типРазбора.URIПространстваИмен ,типРазбора.Имя);
КонецФункции

 

При помощи этого кода легко и быстро можно превратить входящий xml в структуру и затем уже работать с ней в своем приложении.

Вот так будет выглядеть корневой элемент

 

На этом скриншоте - элементы массива (кстати, если XML  - простой (нет пересекающихся имен типов) можно легко отказаться от описания типа)

 

 

Так выглядит загруженный элемент one (обратите внимание что тэг age - уже приведен к числу, согласно схемы)

 

 

 

В обработке прикрепленной к заметке — тот же самый код (плюс несколько несложных сервисных функций)

 

 

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
чтение
.zip 5,83Kb
08.02.14
28
.zip 1 5,83Kb 28 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Яков Коган (Yashazz) 09.02.14 15:23
Пхе. В своё время я написал функцию-универсалку, которая любой XDTO-объект раздербанивает в коллекции 1С (например, в дерево, в строках которого массивы, или структуры, или ещё что, короче, полностью соответствуя структуре исходного объекта). Короче, усложнённый вариант вашей версии. Разумеется, исходя из его URI и фабрики. Но и то публиковать не стал, ибо техническая вспомогательная хрень.

А вы, автор, совсем простые вещи эдак разжёвываете... Зачем? Всё равно, что перебор элементов массива объяснять статьёй на 5 страниц.

Кстати, конечно же, можно определять факт "списочности" иначе. Например, навскидку, так:
Если СвойствоXDTO.НижняяГраница=0 и СвойствоXDTO.ВерхняяГраница=-1 Тогда // списочный
ну или учитывать, что кол-во в списке может быть ограничено, и тогда уж исходя из него ))

2. Валентин Бомбин (so-quest) 09.02.14 19:38
вы абсолютно во всем правы. Для себя скачал вашу разработку http://infostart.ru/public/203514/ буду неделю изучать и приобщаться к мудрости.

И да, - в заголовке ясно указано - любите СП. Но чукча же не читатель...
3. Александр Зубцов (iov) 10.02.14 15:42
В закладочки на память. Автору спасибо очень полезная статья.
4. Надежда (WEBBY) 10.02.14 23:05
Здорово! Спасибо автору!
6. Vasiliy Gololobov (GVasiliy) 13.02.14 12:56
Автор, поменяйте "попытку" на проверку:

ТипЗнч( ... ) = Тип("СписокXDTO")

ТипЗнч( ... ) = Тип("ОбъектXDTO").
7. Валентин Бомбин (so-quest) 13.02.14 13:08
да я бы с удовольствием, но анализируется не значение, а свойство. и все обламывает...
В (0) опытные разработчики советуют вариант без попытки (там тоже есть ограничения)

в принципе мне хватало всегда проверки
Если х.НижняяГраница=х.ВерхняяГраница и х.ВерхняяГраница=1 Тогда // наверное список
но подобная практика пару раз приводила к ошибкам (правда на 8.1 ) поэтому здесь и сделал через попытку. С точки зрения быстродействия вариант с попыткой проходит - потери не большие, да и читается проще
Dethmontt; +1 Ответить
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа