Случайно наткнулся на статью с алгоритмом загрузки XML-строки в дерево значений и подумал, а не проще ли сделать это через механизм XDTO рекурсивно. На мой взгляд, решение получилось неплохое — даже атрибуты грузит..
Добрый всем день, ночь и прочие времена суток, когда 1С-ники читают данный сайт.
Иногда (может даже часто) нужно загрузить XML в дерево значений. Вот как можно это сделать через механизм XDTO:
Процедура ПоместитьВДерево(Текст)
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(Текст);
Об = ФабрикаXDTO.ПрочитатьXML(Чтение);
Строка = Дерево.ПолучитьЭлементы().Добавить();
Строка.Узел = "Корневой узел";
ПрочитатьУзел(Об, Строка);
КонецПроцедуры
Процедура ПрочитатьУзел(Об, лДерево)
Если ТипЗнч(Об) = Тип("СписокXDTO") Тогда
Для Каждого Ст ИЗ Об Цикл
Строка = лДерево.ПолучитьЭлементы().Добавить();
Строка.Узел = Об.ВладеющееСвойство;
Если ТипЗнч(Ст) = Тип("СписокXDTO") ИЛИ ТипЗнч(Ст) = Тип("ОбъектXDTO") Тогда
ПрочитатьУзел(Ст, Строка);
Иначе
Строка.Элемент = Ст;
КонецЕсли;
КонецЦикла;
Иначе
Для Каждого Ст ИЗ Об.Свойства() Цикл
Строка = лДерево.ПолучитьЭлементы().Добавить();
Строка.Узел = Ст.Имя;
Если ТипЗнч(Об[Ст.Имя]) = Тип("СписокXDTO") ИЛИ ТипЗнч(Об[Ст.Имя]) = Тип("ОбъектXDTO") Тогда
ПрочитатьУзел(Об[Ст.Имя], Строка);
Иначе
Строка.Элемент = Об[Ст.Имя];
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
В данном случае у нас на управляемой форме есть дерево с двумя строковыми колонками «Узел» и «Значение». В процедуру «ПоместитьВДерево» нужно передать текст прочитанного XML-файла, после чего оный загрузится в дерево значений.
Довольно просто для клиента. На сервере будет работать? Ведь строго говоря, вы читаете XML не в дерево значений, а в реквизит формы ДанныеФормыДерево
Это серверные процедуры. Просто в дерево тоже можно прочитать немного изменив код.
(2) starik-2005, может они и серверные, но явно в коде используется данныеФормыДерево, а не дерево значений, поэтому ваш код будет работать только в контексте вызываемой формы, но не в общем модуле.
(3) karpik666, ну это чтобы у читателей была возможность подумать. Я за светлое коммунистическое будущее мыслителей и творцов, а не за общество потребительского кредитования…
Вот такой XML, не загружаются значения, только атрибуты:
<Table:Record name=»CustPickingExportDC» row=»1″>
<Table:Field name=»SalesId»>ФН000000053</Table:Field>
<Table:Field name=»PickingListId»>ФН000000053</Table:Field>
<Table:Field name=»CustAccount»>000000661</Table:Field>
<Table:Field name=»ConsigneeAccount»>000000755</Table:Field>
<Table:Field name=»InventLocationId»/>
<Table:Field name=»DeliveryDate»>2016-11-23</Table:Field>
<Table:Field name=»ManDate»/>
<Table:Field name=»ItemId»>ББ00065B125</Table:Field>
<Table:Field name=»InventQty»>3</Table:Field>
<Table:Field name=»SalesUnit»>кг</Table:Field>
<Table:Field name=»SalesQty»>18</Table:Field>
</Table:Record>
(5) genayo, да, при наличии «Namespace prefix» файл не грузится. Но если его убрать, то все работает:
Также заметил, что при наличии атрибутов у элемента и значение элемента — строка, а не вложенный контейнер, то я не нашел, как получить текст самого элемента у XDTO.
Так ведь было уже:http://infostart.ru/public/414940/
(7) cartograph, ну там просто чтение, а тут в дерево раскладывает прочитанное рекурсивненько. Не чувствуете разницу?
рекурсия, вложенные циклы — есть куда оптимизировать. кажись уже такие штуки на инфостарте не раз публиковали
(9) infostart user, в данном конкретном случае оптимизировать, поверьте, особо некуда — вложенные циклы тут как раз уместны. А рекурсия — это вообще один из немногих способов организовать цикл в функциональном программировании, хотя, конечно, 1С тут в плане функциональности весьма ограничена.
Но если Вы предложите вариант оптимизации — велкам! ))
(6) Вот и я не нашел как чисто через фабрику XDTO такой XML прочитать, пришлось использовать комбинацию XDTO и DOM, что на больших файлах несколько печально. Может, есть идеи как проще такой XML прочитать?
(11) как показал гугл, такая возможность есть. Видел в паре источников — сейчас не вспомню, в каких.
Не на эту, случайно?
http://infostart.ru/public/14610/
(13)
Неа.
Господа, внезапно узнал, как получить текст элемента при наличии атрибутов из объекта XDTO. Если интересно — могу написать еще одну статью на эту тему.
(15) также интересно через xslt
можно проще просто последовательно читать
код в форме
Показать
код в модуле
Показать
и еще ваш код при более чем одном узле зачем-то лепит лишнюю строку
результат разбора
файл
(17)
На Инфостарте масса обработок, которые делают подобное.
По поводу текущей обработки, то она рекурсивно преобразует в дерево именно прочитанный XDTO-объект.
По поводу списка, то, полагаю, нужно посмотреть, как прочитался сам файл в объект XDTO.. У меня в коде при наличии списка XDTO в свойстве это свойство сначала создается. Решить можно просто — проверять, что в свойстве список и не создавать для него отдельную ветку дерева, а разворачивать в текущую.
(18)
это понятно ) просто думал бага а это фича )
(11) нужно создать правильный пакет XDTO. Например такой, как во вложении. В нем значение элемента имеет тип число, а атрибут строка.
Ну судя по коду и скрину должно быть
Больше придирка, а по делу — спасибо)
(21)
Истину глаголишь )))
Почему то тут не принимают во внимание что если у вас серверная база данных то это работать не будет.
В этой процедуре Результат[0] передаётся с клиентской машины. На сервере этого пути не будет Выдаст ошибку.
(23)
На сервере нет, но данная процедура, если мне не изменяет память, клиентская, которая читает текст и передает его в:
Показать