Приветствую вас, друзья. Хочу поделиться опытом работы с файлами XML, возможно, пригодится начинающим в этом деле )
1 пример - запись\чтение XML, выгрузим документ в xml файл и загрузим его обратно
2 пример, выгрузка номенклатуры в идентичную конфигурацию по COM Соединению.
Для выгрузки документа в базу с другой конфигурацией будем объявлять элементы и пространства имен вручную.
&НаКлиенте
Функция ПолучитьПутьКФайлу(Режим)
ЗаписьXML = Новый ЗаписьXML;
///1 ВАРИАНТ, Прописываем путь к фалу, при записи - файл будет перезаписываться
ПутьКФайлу = "d:\Temp\Test.XML";
///2 ВАРИАНТ, Указываем путь при сохранении/открытии
Диалог = Новый ДиалогВыбораФайла(Режим);
Диалог.Заголовок = "Выбрать";
Диалог.Фильтр = "XML (*.xml)|*.xml";
Диалог.МножественныйВыбор = Ложь;
Диалог.Каталог = "F:\"; //При желании, (Открывается этот диск по умолчанию)
Если Диалог.Выбрать() Тогда
ПутьКФайлу = Диалог.ПолноеИмяФайла;
Иначе
возврат Неопределено;
КонецЕсли;
Возврат ПутьКФайлу ;
КонецФункции
&НаКлиенте
Процедура ЗаписьВРучную_XML()
ПутьКФайлу = ПолучитьПутьКФайлу(РежимДиалогаВыбораФайла.Сохранение);
Если ПутьКФайлу = Неопределено Тогда ///Если не выбран путь к фалу прерываем операцию
возврат;
КонецЕсли;
Документ = СсылкаНаДокумент; /// СсылкаНаДокумент - реквизит со ссылкой на документ "ПоступлениеТоваров"
ЗаписьXML.ОткрытьФайл(ПутьКФайлу, "UTF-8"); //Открываем файл для записи, указываем кодировку
ЗаписьXML.ЗаписатьОбъявлениеXML(); // Записываем объявление XML
ЗаписьXML.ЗаписатьНачалоЭлемента("ПоступлениеТоваров"); // Начало элемента Документа "ПоступлениеТоваров"
ЗаписьXML.ЗаписатьАтрибут("Код",Строка(Документ.Код));
ЗаписьXML.ЗаписатьАтрибут("Дата",Строка(Документ.Дата));
ЗаписьXML.ЗаписатьАтрибут("Номер",Строка(Документ.Номер));
ЗаписьXML.ЗаписатьАтрибут("Ответственный",Строка(Документ.Ответственный));
ЗаписьXML.ЗаписатьАтрибут("Комментарии",Строка(Документ.Комментарии));
ЗаписьXML.ЗаписатьАтрибут("Склад",Строка(Документ.Склад));
///Запись табличной части "Товары"
Для Каждого выборка из Документ.Товары Цикл // Начинаем выгружать табличную часть "Товары"
ЗаписьXML.ЗаписатьНачалоЭлемента("ТаблицаТовары"); // Начало элемента "ТаблицаТовары"
ЗаписьXML.ЗаписатьАтрибут("Номенклатура",Строка(Выборка.Номенклатура));
//ЗаписьXML.ЗаписатьАтрибут("КодНоменклатуры",Строка(Выборка.Номенклатура.Код)); ///ЕСЛИ СОВПАДАЮТ КОДЫ В БАЗАХ, МОЖНО ПРОИЗВОДИТЬ ПОИСК ПО КОДУ ПРИ ЧТЕНИИ
ЗаписьXML.ЗаписатьАтрибут("Количество",Строка(Выборка.Количество));
ЗаписьXML.ЗаписатьАтрибут("Цена",Строка(Выборка.Цена));
ЗаписьXML.ЗаписатьАтрибут("Сумма",Строка(Выборка.Сумма));
ЗаписьXML.ЗаписатьАтрибут("ЕД",Строка(Выборка.Номенклатура.ЕдиницаИзмерения));
ЗаписьXML.ЗаписатьКонецЭлемента(); // Конец элемента "ТаблицаТовары"
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента(); // Конец элемента "ПоступлениеТоваров"
Сообщить("Файл успешно записан!");
КонецПроцедуры
Чтение файла:
&НаКлиенте
Процедура ЧтениеВРучную_XML()
ПутьКФайлу = ПолучитьПутьКФайлу(РежимДиалогаВыбораФайла.Открытие);
Если ПутьКФайлу = Неопределено Тогда ///Если не выбран путь к фалу прерываем операцию
возврат;
КонецЕсли;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлу); //Открываем файл
///Запись документа должна быть на сервере
ЧтениеXMLНаСервере(ЧтениеXML);
ПоказатьОповещениеПользователя("Уведомление",,"Документ записан!",БиблиотекаКартинок.Успешно32);
КонецПроцедуры
&НаСервере
Процедура ЧтениеXMLНаСервере(ЧтениеXML)
Документ = Документы.ПоступлениеТоваров.СоздатьДокумент(); ///НОВЫЙ ДОКУМЕНТ
Товары = Документ.Товары; ///ТАБЛИЧНАЯ ЧАСТЬ "Товары"
Пока ЧтениеXML.Прочитать() Цикл //Цикл по структуре
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда //Определяем начало элемента
Если ЧтениеXML.Имя = "ПоступлениеТоваров" Тогда
Документ.Код = ЧтениеXML.ЗначениеАтрибута("Код");
Документ.Дата = Дата(ЧтениеXML.ЗначениеАтрибута("Дата")); ///Преобразовываем обратно в дату
Документ.Номер = ЧтениеXML.ЗначениеАтрибута("Номер");
Документ.Ответственный = Справочники.Пользователи.НайтиПоНаименованию(ЧтениеXML.ЗначениеАтрибута("Ответственный"));
Документ.Комментарии = ЧтениеXML.ЗначениеАтрибута("Комментарии");
Документ.Склад = Справочники.Склады.НайтиПоНаименованию(ЧтениеXML.ЗначениеАтрибута("Склад"));
КонецЕсли;
Если ЧтениеXML.Имя = "ТаблицаТовары" Тогда ///Чтение элемента "ТаблицаТовары"
НоваяСтрока = Товары.Добавить();
НоваяСтрока.Номенклатура = Справочники.Пользователи.НайтиПоНаименованию(ЧтениеXML.ЗначениеАтрибута("Номенклатура"));
//НоваяСтрока.КодНоменклатуры = Справочники.Пользователи.НайтиПоКоду(ЧтениеXML.ЗначениеАтрибута("КодНоменклатуры"));
НоваяСтрока.Количество = Число(ЧтениеXML.ЗначениеАтрибута("Количество"));
НоваяСтрока.Цена = Число(ЧтениеXML.ЗначениеАтрибута("Цена"));
НоваяСтрока.Сумма = Число(ЧтениеXML.ЗначениеАтрибута("Сумма"));
НоваяСтрока.ЕД = НоваяСтрока.Номенклатура.ЕденицаИзмерения;
КонецЕсли;
КонецЕсли ;
КонецЦикла;
Документ.Записать(РежимЗаписиДокумента.Проведение);
КонецПроцедуры
Такой метод не всегда эффективен, так как наименования реквизитов могут отличаться, и запись осуществится с ошибками (Например с пустыми реквизитами), вполне подойдет для выгрузки и загрузки определенных элементов между не типовыми конфигурациями. Для более сложных задач (Выгрузка\Загрузка документов и справочников со структурой подчиненности) между не типовыми конфигурациями рекомендуется использовать Конвертацию данных и универсальный обмен данными в формате XML .
Пример Выгрузки и загрузки данных между одинаковыми базами средствами XDTO.
&НаСервере
Процедура ЗаписьСредствамиXDTO_XML()
ПутьКФайлу = ПолучитьПутьКФайлу(РежимДиалогаВыбораФайла.Сохранение);
Если ПутьКФайлу = Неопределено Тогда ///Если не выбран путь к фалу прерываем операцию
возврат;
КонецЕсли;
Документ = СсылкаНаДокумент; /// СсылкаНаДокумент - реквизит со ссылкой на документ "ПоступлениеТоваров"
/////////////////////////////////////////////////////////////////////////
//Выгрузка
Запись = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ПутьКФайлу, "UTF-8"); //Открываем файл для записи, указываем кодировку
//записываем объявление xml файла: <?xml version="1.0"?>
Запись.ЗаписатьОбъявлениеXML();
//записываем корневой элемент, по спецификации xml он может быть только один, назовем его "Данные"
Запись.ЗаписатьНачалоЭлемента("ПоступлениеТоваров");
//для того чтобы пространства имен не объявлялись сериализатором в кажом элементе, пишем их в корневой элемент
//они будут работать на все вложеные элементы
//пространство имен по-умолчанию
Запись.ЗаписатьСоответствиеПространстваИмен("", "http://v8.1c.ru/8.1/data/enterprise/current-config");
//пространства имен остальные префиксы
Запись.ЗаписатьСоответствиеПространстваИмен("xsd", "http://www.w3.org/2001/XMLSchema");
Запись.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance");
//вместо этого кода в боевой реализации выгрузки будет создание ОбъектаXDTO и его сериализация
//через ФабрикуXDTO и загруженные в нее схемы конфигурации приемника
СериализаторXDTO.ЗаписатьXML(Запись, Документ.ПолучитьОбъект());
/////ПРИМЕР ЗАПИСИ НЕСКОЛЬКИХ ДОКУМЕНТОВ
//Выборка = Справочники.ПоступлениеТоваров.Выбрать();
//Пока Выборка.Следующий() Цикл
// СериализаторXDTO.ЗаписатьXML(Запись, Выборка.ПолучитьОбъект());
//КонецЦикла;
//записываем конец корневого элемента
Запись.ЗаписатьКонецЭлемента();
Сообщить("Файл успешно записан!");
//// посмотреть содержимое xml
//Текст = Запись.Закрыть();
//Сообщить("Содержимое файла:");
//Сообщить(Текст);
КонецПроцедуры
/////////////////////////////////ЗАГРУЗИМ ОБРАТНО
////////////////////////////////////////////////////
&НаКлиенте
Процедура ЧтениеСредствамиXDTO_XML()
ПутьКФайлу = ПолучитьПутьКФайлу(РежимДиалогаВыбораФайла.Открытие);
Если ПутьКФайлу = Неопределено Тогда ///Если не выбран путь к фалу прерываем операцию
возврат;
КонецЕсли;
/////////////////////////////////////////////////////////////////////////
//Загрузка
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ПутьКФайлу); //Открываем файл
///Запись документа должна быть на сервере
ЧтениеXMLНаСервереЧасть2(Чтение);
КонецПроцедуры
&НаСервере
Процедура ЧтениеXMLНаСервереЧасть2(Чтение)
//прочитаем начало xml файла
Чтение.ПерейтиКСодержимому();
//прочитаем начало корневого элемента
Чтение.Прочитать();
//читаем содержимое пока текущим не станет конец корневого элемента, т.к. мы писали туда только целые элементы справочника,
//а сериализатор читает каждый из их полностью, то мы упремся именно в конец корневого
Пока Чтение.ТипУзла<>ТипУзлаXML.КонецЭлемента Цикл
//читаем очередной элемент справочника
Объект = СериализаторXDTO.ПрочитатьXML(Чтение);
//покажем что прочитали, осталось только записать объект
Сообщить(""+ТипЗнч(Объект)+" - "+Объект);
Объект.Записать(РежимЗаписиДокумента.Проведение);
КонецЦикла;
Чтение.Закрыть();
КонецПроцедуры
Пример выгрузки номенклатуры в одинаковую базу, без сохранения файла XML на диске:
&НаСервере
Функция ПодключениеПоCOM()
//КаталогБазыДанных="C:\ЗУП3"; ///ФАЙЛОВАЯ БАЗА
БазаДанных ="ZUP3"; ///СЕРВЕР
Сервер ="Server1";
Пользователь ="Admin";
Пароль ="Admin";
V8 = Новый COMОбъект("V83.ComConnector");
//Открытие = "file='" + КаталогБазыДанных + "'; usr='" + Пользователь + "'; pwd='" + Пароль + "';"; /// ФАЙЛОВОЕ
Открытие= "srvr='" + Сервер + "'; ref='" + БазаДанных + "'; usr='" + Пользователь + "'; pwd='" + Пароль + "';"; /// СЕРВЕРНОЕ
Соединение = V8.Connect(Открытие);
Возврат Соединение;
КонецФункции
&НаСервере
Процедура ПодключитьсяИЗаписать()
Соединение = ПодключениеПоCOM();
/////////////////////////////////////////////////////////////////////////
//Выгрузка
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
//записываем объявление xml файла: <?xml version="1.0"?>
Запись.ЗаписатьОбъявлениеXML();
//записываем корневой элемент, по спецификации xml он может быть только один, назовем его "Данные"
Запись.ЗаписатьНачалоЭлемента("Данные");
//для того чтобы пространства имен не объявлялись сериализатором в кажом элементе, пишем их в корневой элемент
//они будут работать на все вложеные элементы
//пространство имен по-умолчанию
Запись.ЗаписатьСоответствиеПространстваИмен("", "http://v8.1c.ru/8.1/data/enterprise/current-config");
//пространства имен остальные префиксы
Запись.ЗаписатьСоответствиеПространстваИмен("xsd", "http://www.w3.org/2001/XMLSchema");
Запись.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance");
//ограничение количества выгружаемых элементов для примера
Кол = 4;
Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
//вместо этого кода в боевой реализации выгрузки будет создание ОбъектаXDTO и его сериализация
//через ФабрикуXDTO и загруженные в нее схемы конфигурации приемника
СериализаторXDTO.ЗаписатьXML(Запись, Выборка.ПолучитьОбъект());
//
Кол = Кол - 1;
Если Кол=0 Тогда
Прервать;
КонецЕсли;
КонецЦикла;
//записываем конец корневого элемента
Запись.ЗаписатьКонецЭлемента();
Текст = Запись.Закрыть();
//а теперь загрузим это в новую базу
/////////////////////////////////////////////////////////////////////////
//Загрузка
Чтение = Соединение.NewObject("ЧтениеXML");
Чтение.УстановитьСтроку(Текст);
//прочитаем начало xml файла
Чтение.ПерейтиКСодержимому();
//прочитаем начало корневого элемента
Чтение.Прочитать();
//читаем содержимое пока текущим не станет конец корневого элемента, т.к. мы писали туда только целые элементы справочника,
//а сериализатор читает каждый из их полностью, то мы упремся именно в конец корневого
Пока Чтение.ТипУзла<>ТипУзлаXML.КонецЭлемента Цикл
//читаем очередной элемент справочника
Объект = Соединение.СериализаторXDTO.ПрочитатьXML(Чтение);
//покажем что прочитали, осталось только записать объект
// Сообщить(""+ТипЗнч(Объект)+" - "+Объект);
//Запишем..
Объект.Записать();
КонецЦикла;
Чтение.Закрыть();
Сообщить("Операция завершена!");
КонецПроцедуры
Кстати, можно использовать данный метод между не типовыми конфигурациями, без использования "СериализаторXDTO" как в первом примере )
Спасибо за внимания! Прошу строго не судить ) возможно данный пример поможет именно для решение вашей задачи !) Удачи (=
Буду рад услышать более эффективные решения для подобных задач ! Спасибо !)