Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.11.24;
Скачать: CL | DM;

Вниз

загрузка 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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.016 c
3-78764
pashaz
2003-11-02 20:33
2003.11.24
вывод в DBGrid


1-78926
Pepperok
2003-11-12 14:37
2003.11.24
Содержимое ListBox`a


6-79083
Barmutik
2003-08-17 12:46
2003.11.24
WebBrowser + AutoComplete имена пользователей и пароли


14-79168
shved111
2003-10-31 18:48
2003.11.24
нужна прога на Дельфи. срочно. ОПЛАЧУ. (Москва)


3-78784
Islander
2003-11-05 15:25
2003.11.24
Как проверить данные перед посылкой в БД, работая через ADO