![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
загрузка XML в DataSet
незнайка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
А какая у тебя БД?