有关将数据库中数据转换为XML文件的问题?(200分)

  • 主题发起人 主题发起人 ngdsjck
  • 开始时间 开始时间
N

ngdsjck

Unregistered / Unconfirmed
GUEST, unregistred user!
在实际应用,我后台用的是ACCESS数据库,前台用DELPHI开发,请问将数据库的数据转换为XML文件?另外,请问DTD文件起的作用是什么?
 
采用ADO来连Access, ADOQuery.SaveToFile();可以将结果集保存为XML;
示例: ADOQuery.SQL.Text := 'select * from Table';
ADOQuery.Open ;
ADOQuery.SaveToFile('1.xml');
ADOQuery.Close ;
ADOQuery.LoadFromFile('1.xml');
ADOQuery.Open;
 
看李维的ado/mts/com+高级程序设计那本书
 
procedure TFormADOExlporeMain.InportXML;
var
Tbls:TStringList;
i:integer;
begin
Tbls:=TStringList.Create;
FormMsg.Show;
FormMsg.MemoMsg.Lines.Clear;
try
FormMsg.MemoMsg.Lines.Add('获取数据表列...');
fa.ADOConnection1.GetTableNames(Tbls);
for i:=0 to Tbls.Count-1do
begin
FormMsg.MemoMsg.Lines.Add('导出数据表...'+Tbls);
Application.ProcessMessages;
fa.adoTS.Close;
fa.adoTS.TableName:=Tbls;
fa.adoTS.Open;
if not DirectoryExists(ExtractFilePath(application.ExeName)+'data/') then
CreateDir(ExtractFilePath(application.ExeName)+'data/');
fa.adoTS.SaveToFile(ExtractFilePath(application.ExeName)+'data/'+fa.adoTS.TableName+'.XML',pfXML);
end;
finally
FormMsg.MemoMsg.Lines.Add('导出数据表完毕。('+IntToStr(i+1)+')');
FormMsg.MemoMsg.Lines.Add('数据表输出目录:'+ExtractFilePath(Application.ExeName)+'data/');
ShellExecute(Handle,'open',Pchar(ExtractFilePath(Application.ExeName)+'data/'),Pchar(ExtractFilePath(Application.ExeName)+'data/'),'',SW_MAXIMIZE);
Tbls.Free;
end;
end;
 
也可以自己给数据加标识生成xml,好像大富翁的xml就是自己的加的标识把,dtd是文档类型定义,是xml中标识的定义,用来验证xml文档,好像就是这样吧
 
如何结合DTD文件,来生成相应的XML文件?如生成的文件格式为:
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE SCHEMA SYSTEM "YSFPCGLJK.dtd">
<SCHEMA NAME="YSFPCGL" CHSNAME="货物运输发票清单" SSSQ="200311" CRC="CRC200311_342524751201541.XML">
<TAXPAYER SWSBH="342524751201541" NSRMC="测试用户" SBRQ="2003-11-10" RECORDCOUNT="2" CJLX="CGZK" CJRDM="342524751201541" CJRMC="测试用户">
<Records><Record KPRQ="2003-11-10" FPHM="43221" KPJE="2333" XFSWSBH="211212" XFNSRMC="峰顺货运公司" GFSWSBH="12121" GFNSRMC="亚科公司"/><Record KPRQ="2003-11-10" FPHM="2112" KPJE="121" XFSWSBH="221121" XFNSRMC="峰顺货运公司" GFSWSBH="12121" GFNSRMC="中亚公司"/></Records></TAXPAYER>
</SCHEMA>
 
请各位高手多多指教!
 
function DataSetToXML(ds: TdataSet): WideString;
const
RootName = 'DATAPACKET';
var
Xmldoc : IXMLDOMDocument2;
RootElement,METADATAElement,FIELDSElement,FIELDElement,
ROWDATAElement, ROWElement : IXMLDomElement;
i : integer;
dsField : TField;
begin
result := '';
Xmldoc := CoDOMDocument30.Create as IXMLDOMDocument2;
try
RootElement := Xmldoc.CreateElement(RootName);
//Xmldoc.createAttribute'Version');
RootElement.setAttribute('Version','2.0');
Xmldoc.Appendchild(RootElement);
METADATAElement:= Xmldoc.CreateElement('METADATA');
RootElement.appendChild(METADATAElement);
FIELDSElement:= Xmldoc.CreateElement('FIELDS');
METADATAElement.appendChild(FIELDSElement);
for i :=0 to ds.FieldCount-1do
begin
dsField := ds.Fields;
FIELDElement := Xmldoc.CreateElement('FIELD');
FIELDElement.setAttribute('attrname',dsField.FieldName);
FIELDElement.setAttribute('fieldtype',TDTDataSet.FieldTypeToXMLType(dsField.DataType));
FIELDElement.setAttribute('WIDTH',dsField.DataSize);
FIELDSElement.appendChild(FIELDElement);
end;
ROWDATAElement := Xmldoc.CreateElement('ROWDATA');
RootElement.appendChild(ROWDATAElement);
ds.First;
while not ds.eofdo
begin
ROWElement := Xmldoc.createElement('ROW');
for i:=0 to ds.FieldCount-1do
begin
dsField := ds.Fields;
ROWElement.setAttribute(dsField.FieldName,dsField.Value);
end;
ROWDATAElement.Appendchild(ROWElement);
ds.Next;
end;
result := Xmldoc.xml;
~~~~~~~~~~~
此处改用 Xmldoc.save('d:/d.xml');就可以了!
finally
Xmldoc := nil;
RootElement := nil;
METADATAElement := nil;
FIELDSElement := nil;
FIELDElement := nil;
ROWDATAElement := nil;
ROWElement := nil;
end;
end;

 
再转一个文章吧:
用XML文件作数据库转换中介
转贴自:http://www.gois.ws
本文说明如何从一个Paradox数据库读取数据,生成XML文件,然后将XML文件中的数据插入到一个新的表中。这个新的数据库表可以还是Paradox,也可以是任何Delphi能够访问的数据库。我使用MSXML来解析XML文件,因此你必须使用IE 5.0以上才能使用我的代码。
生成XML文件
转换生成XML文件的过程如下。
XML文件的根名字与表名相同(本例是"country")。
标记<Records>和</Records>之间是各个纪录。
XML中节点元素标记<Field Name>和</Field Name>之间是数据。
<country>
 <Records>
  <Name>Argentina</Name>
  <Capital>Buenos Aires</Capital>
  <Continent>South America</Continent>
  <Area>2777815</Area>
  <Population>32300003</Population>
 </Records>
.
.
</country>
启动一个新应用(application),在主窗口(Main Form)中加入按钮(TButton)和表(TTable)控件。Tabled的设置如下:
DatabaseName : DBDEMOS
Name : Table1
TableName : country (不要后缀 ".db")
Active : True
选择主菜单Project/Import,导入数据库类型。
选择"Microsoft XML, Version 2.0 (version 2.0)",然后点击"Create Unit"按钮。此后,就有一个MSXML_TLB增加到你的工程(project)文件中。要在unit文件的interface段的uses说明里加上MSXML_TLB。
在变量声明中作如下声明:
DataList : TStringlist;
doc : IXMLDOMDocument;
root, child, child1 : IXMLDomElement;
text1, text2 : IXMLDOMText;
nlist : IXMLDOMNodelist;
dataRecord : String;
在执行部分加入以下代码,这就可以从country表中读取数据并生成XML文件。
function TForm1.makeXml(table:TTable):Integer;
var
i : Integer;
xml : String;
begin
try
table.close;
table.open;
xml := table.TableName;
do
c := CreateOleObject('Microsoft.XMLDOM') as IXMLDomDocument;
// 设置XML文件的根名字为"country",与表名相同。
root :=do
c.createElement(xml);
// 把根节点加入到文件中
do
c.appendchild(root);
// 循环产生整个XML文件
while not table.eofdo
begin
// 加入第一级子节点,即纪录
child:=do
c.createElement('Records');
root.appendchild(child);
// 加入第二级子节点
for i:=0 to table.FieldCount-1do
begin
child1:=doc.createElement(table.Fields.FieldName);
child1.appendChild(doc.createTextNode(table.Fields.value));
child.appendchild(child1);
end;
table.Next;
end;
do
c.save(xml+'.xml');
Result:=1;
except
on e:Exceptiondo
Result:=-1;
end;
end;
Call the function in Button1's click event:
procedure TForm1.Button1Click(Sender: TObject);
begin
if makeXml(table1)=1 then
showmessage('XML Generated')
else
showmessage('Error while generating XML File');
end;

随后用IE浏览器打开XML文件(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>
生成新表
XML文件中的数据与原表的数据完全一样。如果直接将数据插入回原表,会导致主索引出错。所以如果真想这么作得话,要事先删除原表。
在主窗口上增加另一个按钮和一个memo控件。为第二个按钮填写以下onclick事件代码。(memo用于显示数据插入成功与否的信息)。
procedure TForm1.Button2Click(Sender: TObject);
var
i,ret_val,count:Integer;
strData:String;
begin
// 注意:在向country表插入数据前,确认XML文件中的数据与原表数据是不同的。或者作一个新表。
try
count:=1;
DataList:=TStringList.Create;
memo1.Clear;
do
c := CreateOleObject('Microsoft.XMLDOM') as IXMLDomDocument;
// 加载country.xml文件
do
c.load('country.xml');
nlist:=doc.getElementsByTagName('Records');
memo1.lines.append('Table Name :country');
memo1.lines.append('---------------------');
for i:=0 to nlist.Get_length-1do
begin
travelChildren(nlist.Get_item(i).Get_childNodes);
// 从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:Exceptiondo
Showmessage(e.message);
end;
end;

nlist是节点列表。在本例中,第一个节点是:
<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等字符串。然后把这个字符串传递给insertintotable函数,让它在country表中插入一条纪录。循环这个过程直至完成遍历整个XML文件。
procedure TForm1.travelChildren(nlist1:IXMLDOMNodeList);
var
j:Integer;
temp:String;
begin
for j:=0 to nlist1.Get_length-1do
begin
// 节点类型1表示是一个实体(entity),节点类型5表示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)
// 节点类型3表示文本节点,即找到数据
else
if(nlist1.Get_item(j).Get_nodeType=3) then
begin
temp:= trim(nlist1.Get_item(j).Get_nodeValue);
dataRecord:=dataRecord+','+temp;
//在memo显示一条纪录
DataList.Add(temp);
// 完成一次节点扫描后包含一条纪录的信息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 - 1do
table1.Fields.AsVariant:=stpt;
try
table1.post;
result:=1;
except
on E:Exceptiondo
result:=-1;
end;
end;

这个程序可以用于任何数据库,因此数据能以XML文件形式在网络(或者在互联网)上传递,实现远程更新。
如有问题,可与我联系。
转贴自:http://www.gois.ws
 
foxyxyan 说的没错,文章长篇大论的没什么实际用途。
 
多人接受答案了。
 
后退
顶部