Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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
1-78995
Virgo
2003-11-14 12:40
2003.11.24
Список программ


9-78746
greenrul
2003-05-16 19:45
2003.11.24
Проблемы с динамически создаваемыми объектами.


14-79170
Дремучий
2003-10-30 21:41
2003.11.24
Excel -- взять значение по ссылке собраной вручную....


11-78875
Kladov
2003-03-06 21:23
2003.11.24
В преддверии версии 1.70


14-79173
Anton.
2003-10-30 12:14
2003.11.24
Слова благодарности





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский