Форум: "Базы";
Текущий архив: 2003.11.24;
Скачать: [xml.tar.bz2];
Вниззагрузка XML в DataSet Найти похожие ветки
← →
незнайка2003 (2003-11-05 08:06) [0]Подскажите, какой существует оптимальный подход в данном вопросе
← →
Mike_Goblin (2003-11-05 08:50) [1]XML бывает разный (в смысле что структура документа XML может быть практически произвольной)
Оптимальный подход в данном вопросе:
1. Посмотреть не реализовал ли кто раньше задачу (Например ClientDataSet умеет сохранять и загружать свое содержимое в XML.)
2. Если нет, то писать парсинг XML документа. (Разобрать содержимое документа). Биться головой в стену не надо есть готовые парсеры (MS XML), Вам остается использовать их для анализа содержимого XML.
PS Телепатические способности почти полностью растратил вчера, неплохо бы ставить вопросы более конкретно :)))
← →
Незнайка2003 (2003-11-05 11:10) [2]Меня интересует как раз вариант 1.
Файл XML формируется из другой программы, выгрузка определенной таблицы. Мне нужно взять этот файл и закачать в свой набор данных. Как это проще и/или правильнее сделать?
При использовании ClientDataSet нужен файл трансформации, как его создать? Есть ли альтернатива ClientDataSet, в смысле другой DataSet, который бы загружал XML?
← →
Незнайка2003 (2003-11-05 12:16) [3]UP
← →
Max_ (2003-11-05 12:17) [4]Да я вчера спрашивал тоже только ничего не валит!
Файл трансформации создай через XML Mapper (утилита в Дельфе такая). Потом создай Data Packet,который и будет сидеть у тебя в СlientDataSet"e:
procedure TForm1.Button1Click(Sender: TObject);
const trans="c:\settings.xtr";
begin
XMLTransform1.SourceXmlFile:="c:\settings.xml";
XMLTransform1.TransformationFile:=trans;
ClientDataSet1.Close;
ClientDataSet1.XMLData:=XMLTransform1.Data;
ClientDataSet1.Open;
end;
этот код создаёт Data Packet из XML фаила!
Проблема в том как потом всё загруженное сохранить в таблице?
Такая штука не работает:
XMLTransformClient1.ApplyUpdates("c:\settings.xml","c:\settings.xtr",-1);
Она постоянно выкидывает ошибку: Parser Error at the top of docoment Line 1 Position 1.
Чего я только не делал и XML фаил исправлял и схемы разные перепробывал- не пашет! Здесь мне подсказали, что надо Файл трансформации как Insert Delta сохранять! И всё, а так 10 ответов было и все на тему рассуждений (что здесь часто и бывает.)
← →
Незнайка2003 (2003-11-05 13:26) [5]Спасибо.
Хотелось бы еще варианты услышать.
На www.torry.net есть соответсвующий импорт, но эти компоненты платные.
← →
bushmen (2003-11-05 13:27) [6]Если тебе нужны уроки по программированию, то иди на курсы. А здесь люди не обязаны лекции читать. А слово "помощь" не означает, что сделают все для тебя.
← →
Незнайка2003 (2003-11-05 13:30) [7]Мне уроки по программированию не нужны, я хочу узнать, делал ли кто-нибудь данное действие и каким образом. Зачем на одни и те же грабли наступать?
> bushmen © (05.11.03 13:27) [6]
А если нечего сказать, я считаю лучше промолчать
← →
bushmen (2003-11-05 13:32) [8]>Незнайка2003
Это была реплика на [4] И всё, а так 10 ответов было и все на тему рассуждений (что здесь часто и бывает.)
Извини, если ты решил, что это относится к тебе
← →
Незнайка2003 (2003-11-05 13:48) [9]
> bushmen © (05.11.03 13:32) [8]
Понял, извинения приняты :)
В принципе получается, что задача стандартная, возникает у многих. И вариантов решения пока только 2:
1. Парсить самостоятельно. Это не удобно, для каждого из наборов данных придется писать самостоятельную процедуру разбора. Да и долго это, а если нужно то только 1 раз закачать.
2. Использование TClientDataSet. Это мощный инструмент, большинство возможностей которого не используется. Вот и встает вопрос: неужели придется таскать все dll (знаю что их несколько) на пользовательские машины для того чтобы загружать XML?
Получается, что стандартная задача не имеет стандартного решения.
← →
bushmen (2003-11-05 13:51) [10]>Незнайка2003
А какая у тебя БД?
← →
Незнайка2003 (2003-11-05 13:53) [11]Никакая, в данной задаче DataSet в памяти.
← →
Max_ (2003-11-05 13:54) [12]>bushmen
Мне уроки по програмированию не нужны и я не сомневаюсь, что в этом разделе да и наверное во многих других разбираюсь не хуже, а может и лучше Вас, ув. тов. Bushmen! У меня возник вопрос и я его коректно задаю и не умоляю что бы мне кто-нибудь ответил, но и не прошу что бы мне бэйцлы крутили разного рода заморочками, типа: а зачем тебе это надо или используй методы сервера!!! Так может мне вообще космическую энергию использовать или магию! Когда я вижу вопрос и не знаю ответа я не лезу в первых рядах коментировать ситуацию- зачем человека заблуждать. Есть точный ответ- тогда его даю!
С уважением!
← →
sokohigh (2003-11-05 14:14) [13]> Max_
У меня все работало следующим образом:
1. Создал ClientDataSet с Persistent-полями.
2. В дизайн-тайме через его контекстное меню: Create DataSet, Save to MyBase XML table (задаешь имя файла)
3. В XMLMapper-е: Open DataPacket (полученный в 2. файл), Open XML Document (XML, кот. ты хочешь залить в базу), определяешь соответствие полей, задаешь направл. преобразования и тип дельты, тестируешь файл файл трансформации на заданных файлах и сохраняешь его.
← →
sokohigh (2003-11-05 14:23) [14]>Max_
В заверешение [13]: Ну а потом используешь полученный проверенный файл трансформации без проблем (почти :))
← →
Max_ (2003-11-05 14:33) [15]Ok, а как ты всё в базе сохраняешь? Я ведь хочу из XML в базу сохранить. У меня ClientDataSet присоединен к пустой таблице в базе и есть XML из которого загрузить. DataPacket и Transformation file у меня есть,загрузить всё это в ClientDataSet1.XMLData тоже могу, но в таблицу как сохранить?
← →
sokohigh (2003-11-05 14:37) [16]>Незнайка2003
Ну, не знаю, чего в ClientDataSet (то есть в Borland MIDAS) лишнего, скорее наоборот - хотелось бы большего, а то, что есть, ИМХО, стоит использовать. А dll вроде одна - MIDAS.DLL, но можно и без нее - если добавить в uses MidasLib.
← →
sokohigh (2003-11-05 14:42) [17]Вроде двумя способами получается:
1. Через ClientDataSet.ApplyUpdates, если ты в него предварительно именно дельту загрузил, а не просто набор записей.
2. Как ты сам сказал - через XMLTransformClient.ApplyUpdates, опять-таки, если ему в качестве параметра инсерт-дельта XML-данные передавать.
← →
sokohigh (2003-11-05 14:49) [18]Можно в порядке расширения кругозора сохранить CDS, у которого ChangeCount>0 в XML-файл и посмотреть, чем измененные записи (т.е.Delta) отличаются от обычных.
← →
Max_ (2003-11-05 14:58) [19]А как мне дельту загрузить, если она read-only? B том то и дело, что загружается XMLData, a не Delta!
И как установить инсерт-дельту (именно инсерт)?
← →
Малиновский Владимир (2003-11-05 15:12) [20]ПРИМЕР:
Ну, вот я сначала выгружаю из 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;
Все!
← →
sokohigh (2003-11-05 15:14) [21]Не нужно ее грузить ее нужно...:-)
Она сама, эта Delta получится, если ты в Data (или XML Data, что в общем-то то же самое) загрузишь данные, содержащие измененные записи, т.е. Delta - это отфильтрованная Data. Delta появляется, при модификации записей в ClientDataSet (Append, Delete, Edit/Post) или при загрузке в него данных, полученных с использованиием файла трансформации типа инсерт или delete delta.
← →
sokohigh (2003-11-05 15:24) [22]>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:27) [23]>Малиновский Владимир
А в базу у Вас не апдейтится?
← →
Малиновский Владимир (2003-11-05 15:29) [24]Все в конце концов в базу заливается, иначе зачем экспорт делать - то было?
← →
Max_ (2003-11-05 15:53) [25]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 как была пустой так и осталась!
← →
sokohigh (2003-11-05 16:00) [26]>Max_
А c:\sett_trans.xtr" ты сгенерил в XMLMapper как Insert Delta?
← →
sokohigh (2003-11-05 16:02) [27]>Max_
Я бы сказал if ClientDataSet1.ChangeCount>0 then //проверяю
← →
Max_ (2003-11-05 17:34) [28]Всё заработало!!!!!! Спасибо, sokohigh!!!
Кстати, а можно генерить трансформационный фаил програмно (insert delta что бы был)?
← →
sokohigh (2003-11-05 18:27) [29]Не за что ;)
А ты посмотри на этот файл (в IE, например) - в прынципе это ж текст... Только, конечно, не очень-то это удобно. Наверное проще создавать вспомогательный CDS, грузить в него данные из XML и из него записи по одной апендить в CDS, привязанный к базе через провайдера. Можно, видимо, и независимо от структуры сделать.
Когда прочитал про эти фичи ClientDataSet (все вместе Borland называет это BriefCase model), обрадовался: ну, думаю, вот и готовый BackUp/Restore для реляционной базы данных любой структуры. Типа делаем дерево из CDS-ов (с помощью TDataSetField-ов), пишем SQL для извлечения каждого листика дерева, делаем корневому CDS опен, ждем конечно, и делаем SaveToFile (опять ждем). Вот и готовый Backup всей базы в одном XML-файле. Ну и конечно первым делом решил, что для рестора достаточно будет сделать LoadFromFile и ApplyUpdate, наивный... но нет в мире совершенства (или как там у классиков?) приходится еще и трансформации создавать, то есть практически два раза описывать структуру. А ведь это обидно: ладно, когда нужно произвольный XML загрузить, а тут ведь та же структура и все равно создавай трансформацию.
В общем, некрасивое это решение - с трансформациями. Может кто лучше чего придумал? Было бы оччень интересно.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2003.11.24;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.011 c