Однаждый Джоель Мозес (англ. 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 — уже приведен к числу, согласно схемы)
В обработке прикрепленной к заметке — тот же самый код (плюс несколько несложных сервисных функций)
Пхе. В своё время я написал функцию-универсалку, которая любой XDTO-объект раздербанивает в коллекции 1С (например, в дерево, в строках которого массивы, или структуры, или ещё что, короче, полностью соответствуя структуре исходного объекта). Короче, усложнённый вариант вашей версии. Разумеется, исходя из его URI и фабрики. Но и то публиковать не стал, ибо техническая вспомогательная хрень.
А вы, автор, совсем простые вещи эдак разжёвываете… Зачем? Всё равно, что перебор элементов массива объяснять статьёй на 5 страниц.
Кстати, конечно же, можно определять факт «списочности» иначе. Например, навскидку, так:
Если СвойствоXDTO.НижняяГраница=0 и СвойствоXDTO.ВерхняяГраница=-1 Тогда // списочный
ну или учитывать, что кол-во в списке может быть ограничено, и тогда уж исходя из него ))
вы абсолютно во всем правы. Для себя скачал вашу разработкуhttp://infostart.ru/public/203514/ буду неделю изучать и приобщаться к мудрости.
И да, — в заголовке ясно указано — любите СП. Но чукча же не читатель…
В закладочки на память. Автору спасибо очень полезная статья.
Здорово! Спасибо автору!
Автор, поменяйте «попытку» на проверку:
ТипЗнч( … ) = Тип(«СписокXDTO»)
ТипЗнч( … ) = Тип(«ОбъектXDTO»).
да я бы с удовольствием, но анализируется не значение, а свойство. и все обламывает…
В (0) опытные разработчики советуют вариант без попытки (там тоже есть ограничения)
в принципе мне хватало всегда проверки
Если х.НижняяГраница=х.ВерхняяГраница и х.ВерхняяГраница=1 Тогда // наверное список
но подобная практика пару раз приводила к ошибкам (правда на 8.1 ) поэтому здесь и сделал через попытку. С точки зрения быстродействия вариант с попыткой проходит — потери не большие, да и читается проще