教程中国
PHOTOSHOP CS9.0中文版 MAYA 8.5 FOR WINDOWS Corel Painter v9.0 Flash MX2004 中文版 Illustrator cs2 中文版
VC++6.0含sp6 中英文版 VB6.0 +sp6 简体中文版 Borland Delphi 7汉化版 MSDN for vb6.0中文版 Visual Studio 2005简体
教程中国下属 文件存储共享专家BIBIDU.COM 提供大型软件,教材,源码,电影,音乐,图书等下载 更多精品请点此进入
  您目前所在位置: 教程中国 >> 编程基地 >> Delphi >> 由数据库数据生成XML的方法 RSS订阅
由数据库数据生成XML的方法
教程(视频,书籍)下载:  ASP.NET AutoCAD 数据库 C# ASP java photoshop 网页设计 delphi 3dmax Flash C++ VB 张孝祥 实例   更多请进入BIBIDU搜索
IT搜索引擎   
   procedure DatasetToXML(Dataset: TDataset; FileName: string); 
unit DS2XML; 

interface 

uses 
Classes, DB; 

procedure DatasetToXML(Dataset: TDataset; FileName: string); 

implementation 

uses 
SysUtils; 

var 
SourceBuffer: PChar; 

procedure WriteString(Stream: TFileStream; s: string); 
begin 
StrPCopy(SourceBuffer, s); 
Stream.Write(SourceBuffer[0], StrLen(SourceBuffer)); 
end; 

procedure WriteFileBegin(Stream: TFileStream; Dataset: TDataset); 

function XMLFieldType(fld: TField): string; 
begin 
case fld.DataType of 
ftString: Result := ’"string" WIDTH="’ + IntToStr(fld.Size) + ’"’; 
ftSmallint: Result := ’"i4"’; //?? 
ftInteger: Result := ’"i4"’; 
ftWord: Result := ’"i4"’; //?? 
ftBoolean: Result := ’"boolean"’; 
ftAutoInc: Result := ’"i4" SUBTYPE="Autoinc"’; 
ftFloat: Result := ’"r8"’; 
ftCurrency: Result := ’"r8" SUBTYPE="Money"’; 
ftBCD: Result := ’"r8"’; //?? 
ftDate: Result := ’"date"’; 
ftTime: Result := ’"time"’; //?? 
ftDateTime: Result := ’"datetime"’; 
else 
end; 
if fld.Required then 
Result := Result + ’ required="true"’; 
if fld.Readonly then 
Result := Result + ’ readonly="true"’; 
end; 

var 
i: Integer; 
begin 
WriteString(Stream, ’ ’ + 
’’); 
WriteString(Stream, ’’); 

{write th metadata} 
with Dataset do 
for i := 0 to FieldCount-1 do 
begin 
WriteString(Stream, ’’); 
end; 
WriteString(Stream, ’’); 
WriteString(Stream, ’’); 
WriteString(Stream, ’’); 
end; 

procedure WriteFileEnd(Stream: TFileStream); 
begin 
WriteString(Stream, ’’); 
end; 

procedure WriteRowStart(Stream: TFileStream; IsAddedTitle: Boolean); 
begin 
if not IsAddedTitle then 
WriteString(Stream, ’end; 

procedure WriteRowEnd(Stream: TFileStream; IsAddedTitle: Boolean); 
begin 
if not IsAddedTitle then 
WriteString(Stream, ’/>’); 
end; 

procedure WriteData(Stream: TFileStream; fld: TField; AString: ShortString); 
begin 
if Assigned(fld) and (AString <> ’’) then 
WriteString(Stream, ’ ’ + fld.FieldName + ’="’ + AString + ’"’); 
end; 

function GetFieldStr(Field: TField): string; 

function GetDig(i, j: Word): string; 
begin 
Result := IntToStr(i); 
while (Length(Result) < j) do 
Result := ’0’ + Result; 
end; 

var Hour, Min, Sec, MSec: Word; 
begin 
case Field.DataType of 
ftBoolean: Result := UpperCase(Field.AsString); 
ftDate: Result := FormatDateTime(’yyyymmdd’, Field.AsDateTime); 
ftTime: Result := FormatDateTime(’hhnnss’, Field.AsDateTime); 
ftDateTime: begin 
Result := FormatDateTime(’yyyymmdd’, Field.AsDateTime); 
DecodeTime(Field.AsDateTime, Hour, Min, Sec, MSec); 
if (Hour <> 0) or (Min <> 0) or (Sec <> 0) or (MSec <> 0) then 
Result := Result + ’T’ + GetDig(Hour, 2) + ’:’ + GetDig(Min, 2) + ’:’ + GetDig(Sec, 2) + GetDig(MSec, 3); 
end; 
else 
Result := Field.AsString; 
end; 
end; 


procedure DatasetToXML(Dataset: TDataset; FileName: string); 
var 
Stream: TFileStream; 
bkmark: TBookmark; 
i: Integer; 
begin 
Stream := TFileStream.Create(FileName, fmCreate); 
SourceBuffer := StrAlloc(1024); 
WriteFileBegin(Stream, Dataset); 

with DataSet do 
begin 
DisableControls; 
bkmark := GetBookmark; 
First; 

{write a title row} 
WriteRowStart(Stream, True); 
for i := 0 to FieldCount-1 do 
WriteData(Stream, nil, Fields[i].DisplayLabel); 
{write the end of row} 
WriteRowEnd(Stream, True); 

while (not EOF) do 
begin 
WriteRowStart(Stream, False); 
for i := 0 to FieldCount-1 do 
WriteData(Stream, Fields[i], GetFieldStr(Fields[i])); 
{write the end of row} 
WriteRowEnd(Stream, False); 

Next; 
end; 

GotoBookmark(bkmark); 
EnableControls; 
end; 

WriteFileEnd(Stream); 
Stream.Free; 
StrDispose(SourceBuffer); 
end; 

end. 





生成XML文件。
我使用下面的转换方法:
I . XML文件的根名与表名相同(本例就是country)。
II. 每条来自于表的记录由<record></record>标记区分。
III. 每个来自于表的数据由其字段名标记加以区分。

- <country> 
- <Records> 
<Name>Argentina</Name> 
<Capital>Buenos Aires</Capital> 
<Continent>South America</Continent> 
<Area>2777815</Area> 
<Population>32300003</Population> 
</Records> 



</country> 

建立一个新的应用程序。放置一个Button和Table构件于主窗体上。设置表属性如下:
DatabaseName : DBDEMOS 
Name : Table1 
TableName : country (Remove the extention ".db") 
Active : True 

选择 Project/Import Type library。将会弹出 "Import Type Library" 对话框。从列表中选择 "Microsoft XML,Version 
2.0(version 2.0)" 然后点击 "Create Unit" 按钮。将会有一个 MSXML_TLB 单元加入你的工程.请将 MSXML_TLB 加入你要引用的单元的接口部分。然后在变量部分声明如下变量:
DataList : TStringlist; 
doc : IXMLDOMDocument; 
root,child,child1 : IXMLDomElement; 
text1,text2 : IXMLDOMText; 
nlist : IXMLDOMNodelist; 
dataRecord : String; 

添加makeXml函数到你的单元。它将通过读取DBDEMOS中contry表中的数据生成一个XML文件。
function TForm1.makeXml(table:TTable):Integer; 
var 
i : Integer; 
xml,temp : String; 
begin 
try 
table.close; 
table.open; 
xml := table.TableName; 
doc := CreateOleObject(’Microsoft.XMLDOM’) as IXMLDomDocument; 
//Set the root name of the xml file as that of the table name. 
//In this case "country" 
root := doc.createElement(xml); 
doc.appendchild(root); 
//This while loop will go through the entaire table to generate the xml file 
while not table.eof do 
begin 
//adds the first level children , Records 
child:= doc.createElement(’Records’); 
root.appendchild(child); 
for i:=0 to table.FieldCount-1 do 
begin 
//adds second level children 
child1:=doc.createElement(table.Fields[i].FieldName); 
child.appendchild(child1); 
//Check field types 
case TFieldType(Ord(table.Fields[i].DataType)) of 
ftString: 
begin 
if Table.Fields[i].AsString =’’ then 
temp :=’null’ //Put a default string 
else 
temp := table.Fields[i].AsString; 
end; 

ftInteger, ftWord, ftSmallint: 
begin 
if Table.Fields[i].AsInteger > 0 then 
temp := IntToStr(table.Fields[i].AsInteger) 
else 
temp := ’0’; 
end; 
ftFloat, ftCurrency, ftBCD: 
begin 
if table.Fields[i].AsFloat > 0 then 
temp := FloatToStr(table.Fields[i].AsFloat) 
else 
temp := ’0’; 
end; 
ftBoolean: 
begin 
if table.Fields[i].Value then 
temp:= ’True’ 
else 
temp:= ’False’; 
end; 
ftDate: 
begin 
if (not table.Fields[i].IsNull) or 
(Length(Trim(table.Fields[i].AsString)) > 0) then 
temp := FormatDateTime(’MM/DD/YYYY’, 
table.Fields[i].AsDateTime) 
else 
temp:= ’01/01/2000’; //put a valid default date 
end; 
ftDateTime: 
begin 
if (not table.Fields[i].IsNull) or 
(Length(Trim(table.Fields[i].AsString)) > 0) then 
temp := FormatDateTime(’MM/DD/YYYY hh:nn:ss’, 
Table.Fields[i].AsDateTime) 
else 
temp := ’01/01/2000 00:00:00’; //Put a valid default date and time 
end; 
ftTime: 
begin 
if (not table.Fields[i].IsNull) or 
(Length(Trim(table.Fields[i].AsString)) > 0) then 
temp := FormatDateTime(’hh:nn:ss’, 
table.Fields[i].AsDateTime) 
else 
temp := ’00:00:00’; //Put a valid default time 
end; 
end; 
// 
child1.appendChild(doc.createTextNode(temp)); 
end; 
table.Next; 
end; 
doc.save(xml+’.xml’); 
memo1.lines.Append(doc.xml); 
Result:=1; 
except 
on e:Exception do 
Result:=-1; 
end; 
end; 

在Button1的onclick事件中调用上面的函数
procedure TForm1.Button1Click(Sender: TObject); 
begin 
if makeXml(table1)=1 then 
showmessage(’XML Generated’) 
else 
showmessage(’Error while generating XML File’); 
end; 

如果你用IE 5.0(或以上版本)打开生成的country.xml文件,它看起来会成下面的样子
- <country> 
- <Records> 
<Name>Argentina</Name> 
<Capital>Buenos Aires</Capital> 
<Continent>South America</Continent> 
<Area>2777815</Area> 
<Population>32300003</Population> 
</Records> 
- <Records> 
<Name>Bolivia</Name> 
<Capital>La Paz</Capital> 
<Continent>South America</Continent> 
<Area>1098575</Area> 
<Population>7300000</Population> 
</Records> 



- <Records> 
<Name>Venezuela</Name> 
<Capital>Caracas</Capital> 
<Continent>South America</Continent> 
<Area>912047</Area> 
<Population>19700000</Population> 
</Records> 
</country> 

插入数据

你已经将country表中存在的数据生成了XML文件。因此在这个XML文件中的数据就与country表中是一样的。如果你想将XML文件中的数据插入进country表中又不想删除原来存在的数据的话,将会有主键冲突的错误出现。因此必须先将country表中已经存在的数据删除掉。
添加另一个按钮和一个memo构件于主窗体。在button2的onclick事件中添加如下代码.memo用来显示数据插入中的状态(成功/失败)。
procedure TForm1.Button2Click(Sender: TObject); 
var 
i,ret_val,count:Integer; 
strData:String; 
begin 
//Before inserting data in to the country table,make sure that the data in 
//the generated xml file(country.xml) and country table(DBDEMOS) are 
//different. 
try 
count:=1; 
DataList:=TStringList.Create; 
memo1.Clear; 
doc := CreateOleObject(’Microsoft.XMLDOM’) as IXMLDomDocument; 
//Load country.xml file 
doc.load(’country.xml’); 
nlist:=doc.getElementsByTagName(’Records’); 
memo1.lines.append(’Table Name :country’); 
memo1.lines.append(’---------------------’); 
for i:=0 to nlist.Get_length-1 do 
begin 
travelChildren(nlist.Get_item(i).Get_childNodes); 
//Removes the first character(,) from dataRecord 
strData:=copy(dataRecord,2,length(dataRecord)); 
memo1.lines.append(strData); 
dataRecord:=’’; 
ret_val:=insertintotable(Datalist); 
if ret_val=1 then 
memo1.lines.append(’Data inserted successfully.............!’) 
else if ret_val=-1 then 
memo1.lines.append(’Error while updating.....Try again.....!’); 
memo1.lines.append(’=============================================’ 
+’==(Record no. :’+inttostr(count)+’)’); 
DataList.Clear; 
count:=count+1; 
end; 
except 
on e:Exception do 
Showmessage(e.message); 
end; 
end; 

nlist(refer above program) contains a list of nodes.In our case the first node list is... 

<Records> 
<Name>Argentina</Name> 
<Capital>Buenos Aires</Capital> 
<Continent>South America</Continent> 
<Area>2777815</Area> 
<Population>32300003</Population> 
</Records> 


我们传送此节点列表给一个递归函数,travelchildren。它将递归地沿着节点列表查找文本数据,并将此数据加入TStringList(Datalist)变量中。当完成第一轮后,Datalist中将会包含字符串 Argentina,Buenos Aires,South America,2777815,32300003.最后我们将此stringlist传送给函数 insertintotable,它将完成将一条记录插入 country 表的工作。重复此过程即可完成整个XML文件数据的插入工作。
procedure TForm1.travelChildren(nlist1:IXMLDOMNodeList); 
var 
j:Integer; 
temp:String; 
begin 
for j:=0 to nlist1.Get_length-1 do 
begin 
//node type 1 means an entity and node type 5 means EntityRef 
if((nlist1.Get_item(j).Get_nodeType= 1) or (nlist1.Get_item(j).Get_nodeType=5)) then 
travelChildren(nlist1.Get_item(j).Get_childNodes) 
//node Type 3 means a text node,ie you find the data 
else if(nlist1.Get_item(j).Get_nodeType=3) then 
begin 
temp:= trim(nlist1.Get_item(j).Get_nodeValue); 
dataRecord:=dataRecord+’,’+temp; //this is for displaying a single record on the memo 
DataList.Add(temp); //Datalist will contain one record after completing one full travel through the node list 
end 
end; 
end; 

function TForm1.insertintotable(stpt:TStringList):Integer; 
var 
i:Integer; 
begin 
table1.close; 
table1.open; 
table1.Insert; 
for i := 0 to stpt.Count - 1 do 
begin 
table1.Fields[i].AsVariant:= stpt[i]; 
end; 
try 
table1.post; 
result:=1; 
except 
on E:Exception do 
result:=-1; 
end; 
end; 

结论:
你可以将此程序推广至任何数据库,由此数据可以通过XML文件在网络(即使是internet)中传输并在其实终端上更新数据库。我在生成XML文件中还未考虑特殊字符如 &,<,>,’,’’等等。你可以在生成带这些字符的XML文件时作适合自己需要的改变

来源:编程技术-十度教育
作者:
关键字:方法
发表日期:2006-10-18 13:42:25

网页显示有限 阅读全文请下载本文完整版WORD文档

上一篇:Delphi的消息处理   下一篇:Delphi 组件撰写常问问题


2008-10-14 6:09:16
本文的相类似文章
  • Visual Basic 6中发送邮件的新方法
  • 0X000000该内存不能为read的解决方法
  • 计算机硬盘加密的四种方法
  • 经典:木马病毒万能查杀方法
  • 检查系统漏洞的常用方法
  • IRC后门病毒及手动清除方法
  • 病毒隐身新趋势及应对方法
  • 升级瑞星2005防火墙的方法
  • 浅析各种计算机病毒应对方法
  • 防止脚本病毒执行的通用方法
  • 在学习中进步 在进步中成长 教程中国相随您的成长之路
    华腾联合科技股份有限公司版权所有
    广告联系:Rosibo@163.com