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>BuenosAires</Capital>
<Continent>SouthAmerica</Continent>
<Area>2777815</Area>
<Population>32300003</Population>
</Records>
.
.
.
</country>
建立一个新的应用程序。放置一个Button和Table构件于主窗体上。设置表属性如下:
DatabaseName:DBDEMOS
Name:Table1
TableName:country(Removetheextention".db")
Active:True
选择Project/ImportTypelibrary。将会弹出"ImportTypeLibrary"对话框。从列表中选择"MicrosoftXML,Version
2.0(version2.0)"然后点击"CreateUnit"按钮。将会有一个MSXML_TLB单元加入你的工程.请将MSXML_TLB加入你要引用的单元的接口部分。然后在变量部分声明如下变量:
DataList:TStringlist;
doc:IXMLDOMDocument;
root,child,child1:IXMLDomElement;
text1,text2:IXMLDOMText;
nlist:IXMLDOMNodelist;
dataRecord:String;
添加makeXml函数到你的单元。它将通过读取DBDEMOS中contry表中的数据生成一个XML文件。
functionTForm1.makeXml(table:TTable):Integer;
var
i:Integer;
xml,temp:String;
begin
try
table.close;
table.open;
xml:=table.TableName;
doc:=CreateOleObject('Microsoft.XMLDOM')asIXMLDomDocument;
//Settherootnameofthexmlfileasthatofthetablename.
//Inthiscase"country"
root:=doc.createElement(xml);
doc.appendchild(root);
//Thiswhileloopwillgothroughtheentairetabletogeneratethexmlfile
whilenottable.eofdo
begin
//addsthefirstlevelchildren,Records
child:=doc.createElement('Records');
root.appendchild(child);
fori:=0totable.FieldCount-1do
begin
//addssecondlevelchildren
child1:=doc.createElement(table.Fields[i].FieldName);
child.appendchild(child1);
//Checkfieldtypes
caseTFieldType(Ord(table.Fields[i].DataType))of
ftString:
begin
ifTable.Fields[i].AsString=''then
temp:='null'//Putadefaultstring
else
temp:=table.Fields[i].AsString;
end;
ftInteger,ftWord,ftSmallint:
begin
ifTable.Fields[i].AsInteger>0then
temp:=IntToStr(table.Fields[i].AsInteger)
else
temp:='0';
end;
ftFloat,ftCurrency,ftBCD:
begin
iftable.Fields[i].AsFloat>0then
temp:=FloatToStr(table.Fields[i].AsFloat)
else
temp:='0';
end;
ftBoolean:
begin
iftable.Fields[i].Valuethen
temp:='True'
else
temp:='False';
end;
ftDate:
begin
if(nottable.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';//putavaliddefaultdate
end;
ftDateTime:
begin
if(nottable.Fields[i].IsNull)or
(Length(Trim(table.Fields[i].AsString))>0)then
temp:=FormatDateTime('MM/DD/YYYYhh:nn:ss',
Table.Fields[i].AsDateTime)
else
temp:='01/01/200000:00:00';//Putavaliddefaultdateandtime
end;
ftTime:
begin
if(nottable.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';//Putavaliddefaulttime
end;
end;
//
child1.appendChild(doc.createTextNode(temp));
end;
table.Next;
end;
doc.save(xml+'.xml');
memo1.lines.Append(doc.xml);
Result:=1;
except
one:Exceptiondo
Result:=-1;
end;
end;
在Button1的onclick事件中调用上面的函数
procedureTForm1.Button1Click(Sender:TObject);
begin
ifmakeXml(table1)=1then
showmessage('XMLGenerated')
else
showmessage('ErrorwhilegeneratingXMLFile');
end;
如果你用IE5.0(或以上版本)打开生成的country.xml文件,它看起来会成下面的样子
-<country>
-<Records>
<Name>Argentina</Name>
<Capital>BuenosAires</Capital>
<Continent>SouthAmerica</Continent>
<Area>2777815</Area>
<Population>32300003</Population>
</Records>
-<Records>
<Name>Bolivia</Name>
<Capital>LaPaz</Capital>
<Continent>SouthAmerica</Continent>
<Area>1098575</Area>
<Population>7300000</Population>
</Records>
.
.
.
-<Records>
<Name>Venezuela</Name>
<Capital>Caracas</Capital>
<Continent>SouthAmerica</Continent>
<Area>912047</Area>
<Population>19700000</Population>
</Records>
</country>
插入数据
你已经将country表中存在的数据生成了XML文件。因此在这个XML文件中的数据就与country表中是一样的。如果你想将XML文件中的数据插入进country表中又不想删除原来存在的数据的话,将会有主键冲突的错误出现。因此必须先将country表中已经存在的数据删除掉。
添加另一个按钮和一个memo构件于主窗体。在button2的onclick事件中添加如下代码.memo用来显示数据插入中的状态(成功/失败)。
procedureTForm1.Button2Click(Sender:TObject);
var
i,ret_val,count:Integer;
strData:String;
begin
//Beforeinsertingdataintothecountrytable,makesurethatthedatain
//thegeneratedxmlfile(country.xml)andcountrytable(DBDEMOS)are
//different.
try
count:=1;
DataList:=TStringList.Create;
memo1.Clear;
doc:=CreateOleObject('Microsoft.XMLDOM')asIXMLDomDocument;
//Loadcountry.xmlfile
doc.load('country.xml');
nlist:=doc.getElementsByTagName('Records');
memo1.lines.append('TableName:country');
memo1.lines.append('---------------------');
fori:=0tonlist.Get_length-1do
begin
travelChildren(nlist.Get_item(i).Get_childNodes);
//Removesthefirstcharacter(,)fromdataRecord
strData:=copy(dataRecord,2,length(dataRecord));
memo1.lines.append(strData);
dataRecord:='';
ret_val:=insertintotable(Datalist);
ifret_val=1then
memo1.lines.append('Datainsertedsuccessfully.............!')
elseifret_val=-1then
memo1.lines.append('Errorwhileupdating.....Tryagain.....!');
memo1.lines.append('============================================='
+'==(Recordno.:'+inttostr(count)+')');
DataList.Clear;
count:=count+1;
end;
except
one:Exceptiondo
Showmessage(e.message);
end;
end;
nlist(referaboveprogram)containsalistofnodes.Inourcasethefirstnodelistis...
<Records>
<Name>Argentina</Name>
<Capital>BuenosAires</Capital>
<Continent>SouthAmerica</Continent>
<Area>2777815</Area>
<Population>32300003</Population>
</Records>
我们传送此节点列表给一个递归函数,travelchildren。它将递归地沿着节点列表查找文本数据,并将此数据加入TStringList(Datalist)变量中。当完成第一轮后,Datalist中将会包含字符串Argentina,BuenosAires,SouthAmerica,2777815,32300003.最后我们将此stringlist传送给函数insertintotable,它将完成将一条记录插入country表的工作。重复此过程即可完成整个XML文件数据的插入工作。
procedureTForm1.travelChildren(nlist1:IXMLDOMNodeList);
var
j:Integer;
temp:String;
begin
forj:=0tonlist1.Get_length-1do
begin
//nodetype1meansanentityandnodetype5meansEntityRef
if((nlist1.Get_item(j).Get_nodeType=1)or(nlist1.Get_item(j).Get_nodeType=5))then
travelChildren(nlist1.Get_item(j).Get_childNodes)
//nodeType3meansatextnode,ieyoufindthedata
elseif(nlist1.Get_item(j).Get_nodeType=3)then
begin
temp:=trim(nlist1.Get_item(j).Get_nodeValue);
dataRecord:=dataRecord+','+temp;//thisisfordisplayingasinglerecordonthememo
DataList.Add(temp);//Datalistwillcontainonerecordaftercompletingonefulltravelthroughthenodelist
end
end;
end;
functionTForm1.insertintotable(stpt:TStringList):Integer;
var
i:Integer;
begin
table1.close;
table1.open;
table1.Insert;
fori:=0tostpt.Count-1do
begin
table1.Fields[i].AsVariant:=stpt[i];
end;
try
table1.post;
result:=1;
except
onE:Exceptiondo
result:=-1;
end;
end;
结论:
你可以将此程序推广至任何数据库,由此数据可以通过XML文件在网络(即使是internet)中传输并在其实终端上更新数据库。我在生成XML文件中还未考虑特殊字符如&,<,>,',''等等。你可以在生成带这些字符的XML文件时作适合自己需要的改变
<!--内容结束//-->
分享到:
相关推荐
按照一定规则,将数据库数据生成xml文件
里面包含说明使用方法,主要是mybatis生成mysql 数据库表并生成mapper对象和xml,此jar包请解压后,查看源码
VC 结合XML文件备份远程数据库,主程序分为客户端和服务端,实现的原理及思路:采用VC6.0生成两个工程文件:... 未实现的功能:服务端没有实现直接读取数据库生成指定XML库文件的功能;未实现多线程的发送/接收等。
项目概述:这是一个基于SpringBoot的数据库文档自动生成工具,旨在通过简单的配置,快速生成详尽的数据库文档。该项目采用Java语言开发,包含39个文件,其中Java源文件22个,辅助以HTML、图像资源以及配置文件等。 ...
php生成json和生成xml文件,并带有ajax分页效果,带图带数据库 thinkphp仿百度分页+分页样式,纯属手工源码分享,php+jquery
本源码为基于C#的SmartSQL数据库文档生成工具设计,共包含753个文件,其中cs文件221个,svg文件220个,png图片151张,xaml文件90个,xshd文件18个,dll文件8个,cshtml文件7个,config文件5个,jpg图片4张,js文件4...
13、修复使用MySQL数据库生成的数据长度不正确的问题 14、生成自定义文件功能可以不配置数据源,不选择自定义模板生成文件,可单独用于文件操作,只要不选择模板,JSON参数中也不配置模板就不会连数据库 15、修复...
该源码可以直接放到php环境下进行部署,部署完成后,不需要修改文件,直接访问ip:port/sqldesigner/index.html就可进行直接建模,非常方便,建模完成后,可生成xml文件和sql文件。希望对大家有帮助,谢谢!
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用!...基于Springboot开发的SSM代码生成器源码+项目说明(一键将数据库中的表生成entity、xml、dao、service、html、js、sql代码文件).zip
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子...ssm框架的代码生成器(根据数据库表生成model、dto、dao、mapperXml、service以及controller)(仅支持mysql).zip
就可以生成SSH框架,非常适合做开发,速度超快,有分页,有SQL语句自动生成,一般的查询 删除 添加 修改 更新 分页 过滤器都有,要的自己去下载,不多说 ,可能分数有点搞,这个不要注册码,网上的都不怎么好,不行...
1. 所有SQL语句都放在不同的XML檔中(一个业务类使用一个XML檔),该档可用工具维护。大大节省开发及维护时间。2. 当数据库结构改变时,只需修改SQL配置文件(用DBMap工具维护),而不用改代码(如果结构改变影响到...
7.数据库操作,目前有Access、SqlServer、Oracel (7.1)先配置数据库连接字符串: UsrCustomFun.SqlConn.SqlParameters下根据数据库类型返回一个数据库连接字符串。 (7.2)再执行数据库操作: (7.2.1)UsrCustomFun...
NULL 博文链接:https://yunhuii.iteye.com/blog/892417
【资源说明】 1、该资源内项目代码都是经过测试运行成功,功能正常的情况下才上传...基于Springboot开发的SSM代码生成器源码+项目说明(一键将数据库中的表生成entity、xml、dao、service、html、js、sql代码文件).zip
配置classpath,将generator/lib中的rapid-generator.jar及其它数据库驱动加入classpath 修改generator.xml的数据库连接属性及其它属性 以application的方式运行GeneratorMain类,要生成不同的table,直接修改代码即可 ...
C#源码 insert语句生成器,支持多种数据库
运行文档 我这里只介绍开发环境的运行 下载安装jdk ...在eclipse/myeclipse中打开源码,找到src目录下的common.util.DataSourceTest类,右键运行它,如果报错则证明数据库连接有误,连通可以打印出数据来
DBCHM v1.8.0.0-beta数据库文档生成工具 支持多数据库 支持CHM导出、Word导出、Excel导出、PDF导出、HTML导出、XML导出、MD导出,方便需求对接
【资源说明】 1、该资源内项目代码都是经过测试运行成功,功能正常的情况下才上传的,请放心下载使用。...ssm框架的代码生成器(根据数据库表生成model、dto、dao、mapperXml、service以及controller)(仅支持mysql).zip