Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

загрузка XML в DataSet


Страницы:   1 2

незнайка2003 ©   (2003-11-05 08:06:00) 

Подскажите, какой существует оптимальный подход в данном вопросе


sokohigh   (2003-11-05 18:27:00) [1]

Не за что ;)
А ты посмотри на этот файл (в IE, например) - в прынципе это ж текст... Только, конечно, не очень-то это удобно. Наверное проще создавать вспомогательный CDS, грузить в него данные из XML и из него записи по одной апендить в CDS, привязанный к базе через провайдера. Можно, видимо, и независимо от структуры сделать.

Когда прочитал про эти фичи ClientDataSet (все вместе Borland называет это BriefCase model), обрадовался: ну, думаю, вот и готовый BackUp/Restore для реляционной базы данных любой структуры. Типа делаем дерево из CDS-ов (с помощью TDataSetField-ов), пишем SQL для извлечения каждого листика дерева, делаем корневому CDS опен, ждем конечно, и делаем SaveToFile (опять ждем). Вот и готовый Backup всей базы в одном XML-файле. Ну и конечно первым делом решил, что для рестора достаточно будет сделать LoadFromFile и ApplyUpdate, наивный... но нет в мире совершенства (или как там у классиков?) приходится еще и трансформации создавать, то есть практически два раза описывать структуру. А ведь это обидно: ладно, когда нужно произвольный XML загрузить, а тут ведь та же структура и все равно создавай трансформацию.
В общем, некрасивое это решение - с трансформациями. Может кто лучше чего придумал? Было бы оччень интересно.


Max_   (2003-11-05 17:34:00) [2]

Всё заработало!!!!!! Спасибо, sokohigh!!!
Кстати, а можно генерить трансформационный фаил програмно (insert delta что бы был)?


sokohigh   (2003-11-05 16:02:00) [3]

>Max_
Я бы сказал if ClientDataSet1.ChangeCount>0 then //проверяю


sokohigh   (2003-11-05 16:00:00) [4]

>Max_
А c:\sett_trans.xtr" ты сгенерил в XMLMapper как Insert Delta?


Max_   (2003-11-05 15:53:00) [5]

procedure TForm1.Button1Click(Sender: TObject);
begin
ClientDataSet1.Open; //пустая Oracle таблица!!!
XMLTransform1.SourceXmlFile:="c:\channels.xml"; //исходный XML
XMLTransform1.TransformationFile:="c:\sett_trans.xtr"; //трансф.
ClientDataSet1.XMLData:=XMLTransform1.Data; //генерю Data Packet
if ClientDataSet1.Delta<>null then //проверяю
ShowMessage("Changed");
end;
>а в случае использования XMLTransform это делается автоматически. Проверил- данные появились, а Delta как была пустой так и осталась!


Малиновский Владимир   (2003-11-05 15:29:00) [6]

Все в конце концов в базу заливается, иначе зачем экспорт делать - то было?


sokohigh   (2003-11-05 15:27:00) [7]

>Малиновский Владимир
А в базу у Вас не апдейтится?


sokohigh   (2003-11-05 15:24:00) [8]

>Max_
В [20] Delta получается явно при помощи Insert:
cdtExportSales.Insert;
for j:= 0 to cdtExportSales.FieldCount - 1 do begin
cdtExportSales.FieldByName(dtGrid.Fields[j].FieldName).Value :=
dtGrid.Fields[j].Value;
end;
cdtExportSales.Post;
, а в случае использования XMLTransform это делается автоматически...


sokohigh   (2003-11-05 15:14:00) [9]

Не нужно ее грузить ее нужно...:-)
Она сама, эта Delta получится, если ты в Data (или XML Data, что в общем-то то же самое) загрузишь данные, содержащие измененные записи, т.е. Delta - это отфильтрованная Data. Delta появляется, при модификации записей в ClientDataSet (Append, Delete, Edit/Post) или при загрузке в него данных, полученных с использованиием файла трансформации типа инсерт или delete delta.


Малиновский Владимир   (2003-11-05 15:12:00) [10]

ПРИМЕР:

Ну, вот я сначала выгружаю из DBGRidEh все выделенные строки в XML через ClientDataSet:

На форме лежат:
dbGrid - решетка DBGridEh
dtGrid - ее набор данных
cdtExportSales - клиентский набор данных

procedure Tfrb_Client.actExportExecute(Sender: TObject);
var i,j : integer;
begin
with dbGrid.DataSource.Dataset do
begin
DisableControls;
cdtExportSales.Close; // Создаем клиентский набор данных
cdtExportSales.FieldDefs.Assign(dtGrid.FieldDefs); // ... по образцу
cdtExportSales.CreateDataSet;
cdtExportSales.Open;

try
for I := 0 to dbGrid.SelectedRows.Count - 1 do // Перекачиваем все
begin // выделенные строки
Bookmark := dbGrid.SelectedRows.Items[I];
cdtExportSales.Insert;
for j:= 0 to cdtExportSales.FieldCount - 1 do begin
cdtExportSales.FieldByName(dtGrid.Fields[j].FieldName).Value :=
dtGrid.Fields[j].Value;
end;
cdtExportSales.Post;
end;
frm_ExportClient.CreateAndShowModal([integer(cdtExportSales)]) // Здесь запрашиваем у юзера имя файла,
// куда экспортить, и экспортим его
finally
EnableControls;
cdtExportSales.Close;
end;
end;
dbGrid.Selection.UpdateState;
end;

//-----------
Фрагмент процедуры экспорта:

var
cdtExportSales : TClientDataSet;
addr : Integer;
begin
inherited;
sdExport.FileName := lblPathName.Caption + // Формируем имя файла - sdExport - это лежащий на форме TSaveDialog
dbEdEhPrefix.Text +
FormatDateTime("_YYYYMMDDHHMMSS",Now)+
Root_Exp_C + ".XML";
if sdExport.Execute then begin
lblPathName.Caption := ExtractFilePath(sdExport.FileName);

(Sender as TBitBtn).Enabled := False;
try
addr := a_params[0];
cdtExportSales := TClientDataSet(addr);
if cdtExportSales.RecordCount > 0 then
ExportClients(cdtExportSales)
else begin
ShowMessage("Нет данных!");
end
finally
(Sender as TBitBtn).Enabled := True;
end
end
end;

//--------------
Ну, и сама процедура экспорта
var i : Integer;
FileName : string;
f : file of byte;
begin
lblMsgSales.Caption := "Экспорт данных...";
try

FileName := lblPathName.Caption +
dbEdEhPrefix.Text +
FormatDateTime("_YYYYMMDDHHMMSS",Now)+
Root_Exp_C + ".XML";

DtSet.SaveToFile(FileName, dfXML);

if not FileExists(FileName) then
raise Exception.Create("Файл "+FileName+" Не был создан");

AssignFile(f,FileName);
try
Reset(f);
if FileSize(f) = 0 then
raise Exception.Create("Файл "+FileName+
" был создан с нулевой длиной" +
#10 + "Возможно, мало места! ");
finally
CloseFile(f)
end;

lblMsgSales.Caption := "Готово!"

except
on E: Exception do begin;
lblMsgSales.Caption := "Ошибка!";
ShowMessage("Ошибка при работе с клиентским набором данных:"#13+
e.Message);

end
end;
end;

РЕЗЮМЕ:
1. Создаем набор данных:
cdtExportSales.Close; // Создаем клиентский набор данных
cdtExportSales.FieldDefs.Assign(dtGrid.FieldDefs); // ... по образцу
cdtExportSales.CreateDataSet;
cdtExportSales.Open;

2. Закачиваем в него данные из физического НД:
cdtExportSales.FieldByName(dtGrid.Fields[j].FieldName).Value :=
dtGrid.Fields[j].Value;
3. Экспорт данных
DtSet.SaveToFile(FileName, dfXML);

Все. Импорт - еще проще:

cdsImport.LoadFromFile("FileName");
cdsImport.Open;

Все!


Max_   (2003-11-05 14:58:00) [11]

А как мне дельту загрузить, если она read-only? B том то и дело, что загружается XMLData, a не Delta!
И как установить инсерт-дельту (именно инсерт)?


sokohigh   (2003-11-05 14:49:00) [12]

Можно в порядке расширения кругозора сохранить CDS, у которого ChangeCount>0 в XML-файл и посмотреть, чем измененные записи (т.е.Delta) отличаются от обычных.


sokohigh   (2003-11-05 14:42:00) [13]

Вроде двумя способами получается:
1. Через ClientDataSet.ApplyUpdates, если ты в него предварительно именно дельту загрузил, а не просто набор записей.
2. Как ты сам сказал - через XMLTransformClient.ApplyUpdates, опять-таки, если ему в качестве параметра инсерт-дельта XML-данные передавать.


sokohigh   (2003-11-05 14:37:00) [14]

>Незнайка2003
Ну, не знаю, чего в ClientDataSet (то есть в Borland MIDAS) лишнего, скорее наоборот - хотелось бы большего, а то, что есть, ИМХО, стоит использовать. А dll вроде одна - MIDAS.DLL, но можно и без нее - если добавить в uses MidasLib.


Max_   (2003-11-05 14:33:00) [15]

Ok, а как ты всё в базе сохраняешь? Я ведь хочу из XML в базу сохранить. У меня ClientDataSet присоединен к пустой таблице в базе и есть XML из которого загрузить. DataPacket и Transformation file у меня есть,загрузить всё это в ClientDataSet1.XMLData тоже могу, но в таблицу как сохранить?


sokohigh   (2003-11-05 14:23:00) [16]

>Max_
В заверешение [13]: Ну а потом используешь полученный проверенный файл трансформации без проблем (почти :))


sokohigh   (2003-11-05 14:14:00) [17]

> Max_
У меня все работало следующим образом:
1. Создал ClientDataSet с Persistent-полями.
2. В дизайн-тайме через его контекстное меню: Create DataSet, Save to MyBase XML table (задаешь имя файла)
3. В XMLMapper-е: Open DataPacket (полученный в 2. файл), Open XML Document (XML, кот. ты хочешь залить в базу), определяешь соответствие полей, задаешь направл. преобразования и тип дельты, тестируешь файл файл трансформации на заданных файлах и сохраняешь его.


Max_   (2003-11-05 13:54:00) [18]

>bushmen
Мне уроки по програмированию не нужны и я не сомневаюсь, что в этом разделе да и наверное во многих других разбираюсь не хуже, а может и лучше Вас, ув. тов. Bushmen! У меня возник вопрос и я его коректно задаю и не умоляю что бы мне кто-нибудь ответил, но и не прошу что бы мне бэйцлы крутили разного рода заморочками, типа: а зачем тебе это надо или используй методы сервера!!! Так может мне вообще космическую энергию использовать или магию! Когда я вижу вопрос и не знаю ответа я не лезу в первых рядах коментировать ситуацию- зачем человека заблуждать. Есть точный ответ- тогда его даю!
С уважением!


Незнайка2003   (2003-11-05 13:53:00) [19]

Никакая, в данной задаче DataSet в памяти.


bushmen   (2003-11-05 13:51:00) [20]

>Незнайка2003
А какая у тебя БД?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо