Описание проблемы (лентяям можно пропустить):
На Инфостарте немало статей по работе с XDTO. Они довольно обширные и требуют времени для изучения и не всегда в них находится сразу то, что нужно в данный момент. Эта маленькая статейка для кодера (а ля синтакс-помощник), после которой он сразу сможет загрузить несложный файл обмена из сторонней базы. Честно говоря, чтобы прийти к тому простейшему коду, который указан ниже, мне пришлось читать и о пакетах XDTO, о схемах xml и способе их создания и т.п., получая ту информацию, которая в данный момент мне пока не пригодилась. Все оказалось намного проще.
Собственно суть:
Итак, в качестве примера возьмем образец xml-файла от микрософт.
<?xml version="1.0"?> <PurchaseOrder PurchaseOrderNumber="99503" OrderDate="1999-10-20"> <Address Type="Shipping"> <Name>Ellen Adams</Name> <Street>123 Maple Street</Street> <City>Mill Valley</City> <State>CA</State> <Zip>10999</Zip> <Country>USA</Country> </Address> <Address Type="Billing"> <Name>Tai Yee</Name> <Street>8 Oak Avenue</Street> <City>Old Town</City> <State>PA</State> <Zip>95819</Zip> <Country>USA</Country> </Address> <DeliveryNotes>Please leave packages in shed by driveway.</DeliveryNotes> <Items> <Item PartNumber="872-AA"> <ProductName>Lawnmower</ProductName> <Quantity>1</Quantity> <USPrice>148.95</USPrice> <Comment>Confirm this is electric</Comment> </Item> <Item PartNumber="926-AA"> <ProductName>Baby Monitor</ProductName> <Quantity>2</Quantity> <USPrice>39.98</USPrice> <ShipDate>1999-05-21</ShipDate> </Item> </Items> </PurchaseOrder>
Вкратце, ФабрикаXDTO дает возможность получить xml в виде объекта, где элементы будут являтся свойствами и, следовательно, к ним можно будет обращаться через точку.
А это весь(!) код обхода элементов Adress и Item.
Чтение=Новый ЧтениеXML;
Чтение.ОткрытьФайл(ВыбранноеИмяФайла);
Фабрика=Новый ФабрикаXDTO;
ОбXDTO=Фабрика.ПрочитатьXML(Чтение);
Для Каждого Address из ОбXDTO.Address Цикл
КонецЦикла;
Для Каждого Item из ОбXDTO.Items.Item Цикл
КонецЦикла;
То что показывает отладчик:
Бинго! Теперь можно делать с этими данными все, что угодно.
Возможно, этот метод не подойдет для каких-то сложных задач, но для простейших обменов самое то (имхо).
Теперь осамом главном минусе этого метода и как его обойти по-лентяйски с минимумом кода.
Возьмем наш пример и отсавим в нем только по одному элементу Adress и Item
<?xml version="1.0"?> <PurchaseOrder PurchaseOrderNumber="99503" OrderDate="1999-10-20"> <Address Type="Shipping"> <Name>Ellen Adams</Name> <Street>123 Maple Street</Street> <City>Mill Valley</City> <State>CA</State> <Zip>10999</Zip> <Country>USA</Country> </Address> <DeliveryNotes>Please leave packages in shed by driveway.</DeliveryNotes> <Items> <Item PartNumber="872-AA"> <ProductName>Lawnmower</ProductName> <Quantity>1</Quantity> <USPrice>148.95</USPrice> <Comment>Confirm this is electric</Comment> </Item> </Items> </PurchaseOrder>
Без особого удивления обнаружим, что наш код работать с таким файлом не будет. Поскольку у нас всего по одному элементу в ветке, то ФабрикаXDTO считает,что это не СписокXDTO а ОбъектXDTO, которрый нельзя обойти через цикл.
Для Каждого Address из ОбXDTO.Address Цикл //здесь будет ошибка "Итератор для значения не определен"
КонецЦикла;
Для Каждого Item из ОбXDTO.Items.Item Цикл // и здесь тоже
КонецЦикла;
Не стоит отчаиваться и,тем более, не стоит утруждать себя и перед каждым циклом писать проверку на тип значения элемента, как в этой статье. (а вдруг у вас таких циклов будет 10). За лентяя все сделает маленькая, но очень полезная функция следующего вида:
Функция КоллекцияXDTO(Элемент)
Если ТипЗнч(Элемент)=Тип("ОбъектXDTO") Тогда
МассивXDTO=Новый Массив;
МассивXDTO.Добавить(Элемент);
Возврат МассивXDTO;
КонецЕсли;
Возврат Элемент;
КонецФункции
Для Каждого Address из КоллекцияXDTO(ОбXDTO.Address) Цикл
КонецЦикла;
Для Каждого Item из КоллекцияXDTO(ОбXDTO.Items.Item) Цикл
КонецЦикла;
Ну вот, собственно, и все. Теперь лентяйский метод практически совершенен).