用 XML Data Binding 生成Pas文件后,怎样操作(读写)?(最好有例子) 还有一问: 怎样把 XML包 用IdHttp方式发出去? (以流方式还是字符串) 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 IdHttp方式发用Post方法吧XML Data Binding 生成Pas文件很不好用,可能是我水平问题吧,我宁远自己用TXMLDocument直接访问XML来的更好 TXMLDocument直接访问XML很麻烦,比如要写成这样:XMLDoc.childNodes[1].childNodes[0].childNodes[0].Text:='8888888888'; 多头疼! 希望用合理的方法,我觉得XML Data Binding 生成Pas文件挺不错的,也看得懂,但不太会用,请用过的大哥赐教:) Delphi 6 XML数据绑定 Delphi 6 含有许多更新更强的XML支持功能,增加了XML文件编程,XML数据绑定向导,XML映象和BizSnap(SOAP/XML Web服务)。我在上一篇文章论述了Delphi 6中的XML文件编程(XML Document Programming)。本文是三篇论述Delphi 6中XML功能系列文章的第二篇,论述Delphi 6中的XML数据绑定(XML Data Binding)。XML文件编程XMLDocument组件让我们能够遍历和编辑XML文件。但是在上一篇文章中我提到了,我们只能与无类型节点打交道,必须记住节点元素的名字。这意味着无法进行实时编译调试!幸亏的是,如果Delphi只能处理这样简单的问题就不成其为Delphi了。运用XML的内容相关结构可以做更高级的应用,这就是Delphi 6的XML数据绑定向导(XML Data Binding Wizard)。XML数据绑定在Delphi 6的模块仓库(Object Repository)中可以找到XML数据绑定向导(XML Data Binding Wizard)。程序员能够用它生成相应的接口和类来访问与修改XML文件数据,诸如ClientDataSetXML数据,ADO XML数据,其它XML文件数据(如我们在前文用到的Clinic.xml,本文继续使用这个简单的XML文件作示例)。现在开始吧,启动Delphi 6,在主菜单上选择File | New - Other,然后在仓库中选择XML Data Binding,如图1所示。向导有三个页面。第一页定义XML纲(Schema)或XML文件(本例用Clinic.xml),如图2所示。在资源输入框内输入XML纲(Schema)或XML文件。“选项”(Options)对话框定义编码选项和数据类型映射关系(Data Type map)。以后我们还会谈到这些选项。向导的第二页显示了树结构和节点数据类型(亦即向导生成了些什么样的代码)。图3可以看到我的XML文件结构。可以看到XML文件里描述的嵌套节点(ClinicsType与ClinicType)和单节点(String)。这时可以打开选项(Options)对话框(图4),修改编码(比如修改前缀)和数据类型映射。向导的第三页显示生成的相应接口和类。可以把这些结果保存到文件(例如生成Clinic.xdb)。结果(存储为Clinic.xdb文件)显示如下。我们得到一个ClinicsType类型的Clinics元素,其中包括ClinicType类型的Clinic系列元素。 <?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xdb="http://www.borland.com/schemas/delphi/6.0/XMLDataBinding"> <xs:element name="Clinics" type="ClinicsType"/> <xs:complexType name="ClinicsType"> <xs:annotation> <xs:appinfo xdb:docElement="Clinics"/> </xs:annotation> <xs:sequence> <xs:element name="Clinic" type="ClinicType" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="ClinicType"> <xs:sequence> <xs:element name="Title" type="xs:string"/> <xs:element name="Date" type="xs:string"/> <xs:element name="Topics" type="xs:string"/> </xs:sequence> <xs:attribute name="No" type="xs:string"/> </xs:complexType> </xs:schema>文件同时定义ClinicType类型的Clinic元素包含一系列字符串元素(Title, Date和Topics)。生成代码向导生成的代码可以直接在应用中使用。不幸的是,Delphi 6有时会产生“非法操作”的出错信息。重新执行一遍,它又能工作了。以下是生成的代码(Clinic.pas): {****************************************************} { } { Delphi XML Data Binding } { } { Generated on: 2001/11/07 00:37:00 } { Generated from: D:D6ClinicsrcClinic.xml } { Settings stored in: D:D6ClinicsrcClinic.xdb } { } {****************************************************} unit Clinic; interface uses xmldom, XMLDoc, XMLIntf; type { Forward Decls } IXMLClinicsType = interface; IXMLClinicType = interface; { IXMLClinicsType } IXMLClinicsType = interface(IXMLNodeCollection) ['{06723E03-662D-11D5-81CE-00104BF89DAD}'] { Property Accessors } function Get_Clinic(Index: Integer): IXMLClinicType; { Methods & Properties } function Add: IXMLClinicType; function Insert(const Index: Integer): IXMLClinicType; property Clinic[Index: Integer]: IXMLClinicType read Get_Clinic; default; end; { IXMLClinicType } IXMLClinicType = interface(IXMLNode) ['{06723E04-662D-11D5-81CE-00104BF89DAD}'] { Property Accessors } function Get_No: WideString; function Get_Title: WideString; function Get_Date: WideString; function Get_Topics: WideString; procedure Set_No(Value: WideString); procedure Set_Title(Value: WideString); procedure Set_Date(Value: WideString); procedure Set_Topics(Value: WideString); { Methods & Properties } property No: WideString read Get_No write Set_No; property Title: WideString read Get_Title write Set_Title; property Date: WideString read Get_Date write Set_Date; property Topics: WideString read Get_Topics write Set_Topics; end; { Forward Decls } TXMLClinicsType = class; TXMLClinicType = class; { TXMLClinicsType } TXMLClinicsType = class(TXMLNodeCollection, IXMLClinicsType) protected { IXMLClinicsType } function Get_Clinic(Index: Integer): IXMLClinicType; function Add: IXMLClinicType; function Insert(const Index: Integer): IXMLClinicType; public procedure AfterConstruction; override; end; { TXMLClinicType } TXMLClinicType = class(TXMLNode, IXMLClinicType) protected { IXMLClinicType } function Get_No: WideString; function Get_Title: WideString; function Get_Date: WideString; function Get_Topics: WideString; procedure Set_No(Value: WideString); procedure Set_Title(Value: WideString); procedure Set_Date(Value: WideString); procedure Set_Topics(Value: WideString); end; { Global Functions } function GetClinics(Doc: IXMLDocument): IXMLClinicsType; function LoadClinics(const FileName: WideString): IXMLClinicsType; function NewClinics: IXMLClinicsType;这里有二个接口类型:IXMLClinicsType和IXMLClinicType;用二个类(TXMLClinicsType和TXMLClinicType)来执行这二个接口。另外还有三个全局函数:GetClinics (获得根元素),LoadClinics (从外部XML文件加载)和NewClinics (在内存生成新文件)。用法使用生成的Clinic.pas单元是很容易的。跟前一篇文章的做法一样,使用XMLDocument组件(在Inernet标签内)。不过我们不再使用无类型节点了,我们可以调用GetClinics函数获得IXMLClinicsType类型。以下是具体操作过程:在Delphi 6建立一个新的应用(project)在XML数据绑定向导指引下建立Clinic.pas文件(经过命名存盘 - 译者)在主窗体上加入一个XMLDocument组件,其FileName属性为Clinic.xml在主窗体的OnCreate事件中加入以下代码: procedure TForm1.FormCreate(Sender: TObject); var Clinics: IXMLClinicsType; begin Clinics := GetClinics(XMLDocument1); end;把Clinics变量放到主窗体中是很有用的,这样就可以在主窗体运行期间使用Clinics接口。使用IXMLClinicsType变量类型要比以前使用普通XMLDocument组件方便多了。现在可以通过Get_Clinic方法来获得各个Clinic元素,还可以在特定位置插入新的Clinic元素。用Clinics.Clinic可以获得节点元素,用Getter和Setter方法可以得到或设置元素值。现在可以直接访问No, Title, Date, Topics等属性了: procedure TForm1.ButtonGetClick(Sender: TObject); var Clinic: IXMLClinicType; begin Clinic := Clinics.Clinic[0]; EditNo.Text := Clinic.No; EditTitle.Text := Clinic.Title; EditDate.Text := Clinic.Date; EditTopics.Text := Clinic.Topics end;可以在Clinic.pas中看到,Getter和Setter是方法而不是属性(实际上,我始终认为使用属性更清楚些)。但是Delphi 6让你看到的却是属性描述而不是方法本身(Delphi 6的另一个受欢迎的优点)。将上面这段代码与前一篇文章使用的方法相比较,就能感到操作方便多了。下面的例子在XML树的末尾加入一个节点: procedure TForm1.ButtonAddClick(Sender: TObject); begin with Clinics.Add do begin No := '2001-2-8; // 8th Clinic of the 2nd series of 2001 Title := 'Special Kylix 2 Clinic'; Date := '2001/12/21'; Topics := 'Kylix 2 New Features' end end;如果没有把XMLDocument组件的AutoSave设置为真,可以用以下方法保存更动结果: procedure TForm1.FormDestroy(Sender: TObject); begin XMLDocument1.SaveToFile; end; 多谢上面两位大哥:我直接用的IXMLNode访问,发现一个问题,不得其解,如下:var Root, Head, Body : IXMLNode;begin Root:= XDoc.DocumentElement; Head:= Root.ChildNodes[0]; //包头节点 Body:= Root.ChildNodes[1]; //包体节点 Head.ChildNodes[0].ChildNodes[1].Text:= '0000'; //这样可以 Body.ChildNodes[0].ChildNodes['Name'].Text:= 'Feng'; //这样会填加一个新节点,真是奇怪,百思不得其解 XML文件编程只要稍作设置(设置FileName为clinics.xml和将doAutoSave置为真),就可以激活TXMLDocument组件。激活之后,就可以遍历节点,读取和编辑数据。现在我们可以在XMLDocument里访问各个节点(IXMLNode),递归访问各节点的子节点。例如,可以用一个按钮来获取第一个节点的元素值并将结果写入Memo:procedure TForm1.Button1Click(Sender: TObject);var Clinic: IXMLNode;begin Clinic := XMLDocument1.DocumentElement.ChildNodes[0]; Memo1.Lines.Clear; Memo1.Lines.Add(Clinic.ChildNodes['Title'].Text); Memo1.Lines.Add(Clinic.ChildNodes['Date'].Text); Memo1.Lines.Add(Clinic.ChildNodes['Topics'].Text)end;增加索引指针可以访问其它节点。下面的例子用"current"作索引,通过循环增加"current"的值来遍历节点。我用try-except来防止循环出界。procedure TForm1.Button2Click(Sender: TObject);var Clinic: IXMLNode;begin Inc(current); try Clinic := XMLDocument1.DocumentElement.ChildNodes[current]; Memo1.Lines.Clear; Memo1.Lines.Add(Clinic.ChildNodes['Title'].Text); Memo1.Lines.Add(Clinic.ChildNodes['Date'].Text); Memo1.Lines.Add(Clinic.ChildNodes['Topics'].Text); except on E: Exception do Memo1.Lines.Add(E.Message) endend;除了遍历节点之外,还可以修改子节点的值。下面的代码将第一个节点的标题值加上一个"HOT"前缀。procedure TForm1.Button1Click(Sender: TObject);var Clinic: IXMLNode;begin current := 0; Clinic := XMLDocument1.DocumentElement.ChildNodes[current]; Memo1.Lines.Clear; Clinic.ChildNodes['Title'].Text := 'HOT: ' + Clinic.ChildNodes['Title'].Text; Memo1.Lines.Add(Clinic.ChildNodes['Title'].Text); Memo1.Lines.Add(Clinic.ChildNodes['Date'].Text); Memo1.Lines.Add(Clinic.ChildNodes['Topics'].Text);end;还可以增删节点。下面的代码增加一个子节点并赋予缺省值:procedure TForm1.Button1Click(Sender: TObject);var Clinic: IXMLNode;begin Clinic := XMLDocument1.DocumentElement.AddChild('Clinic'); Clinic.ChildNodes['Title'].Text := 'Title'; Clinic.ChildNodes['Date'].Text := 'Date'; Clinic.ChildNodes['Topics'].Text := 'Topics';end; 翻译啊 求助insert into select 问题 怎样可以通过delphi程序,将已知的EXCEL文件中的数据导入到指定的数据库中去,在线等待! 将adoquery数据集的内容导出到word文件中。 在線求sql語句,馬上給分 case问题 DELPHI的VCL继承关系图在哪有下载的?? 有关DELPHI中SQL动态查询的问题 请帮忙想一下?—————————————————— 88分抢答,Dbgrid里能不能实现自动换行?或者有没有实现该功能增强的控件。 关于MDI窗体的问题!(请问有没有人碰到过类似的问题?) 用copymemory复制string的问题
Delphi 6 含有许多更新更强的XML支持功能,增加了XML文件编程,XML数据绑定向导,XML映象和BizSnap(SOAP/XML Web服务)。我在上一篇文章论述了Delphi 6中的XML文件编程(XML Document Programming)。本文是三篇论述Delphi 6中XML功能系列文章的第二篇,论述Delphi 6中的XML数据绑定(XML Data Binding)。XML文件编程
XMLDocument组件让我们能够遍历和编辑XML文件。但是在上一篇文章中我提到了,我们只能与无类型节点打交道,必须记住节点元素的名字。这意味着无法进行实时编译调试!幸亏的是,如果Delphi只能处理这样简单的问题就不成其为Delphi了。运用XML的内容相关结构可以做更高级的应用,这就是Delphi 6的XML数据绑定向导(XML Data Binding Wizard)。XML数据绑定
在Delphi 6的模块仓库(Object Repository)中可以找到XML数据绑定向导(XML Data Binding Wizard)。程序员能够用它生成相应的接口和类来访问与修改XML文件数据,诸如ClientDataSetXML数据,ADO XML数据,其它XML文件数据(如我们在前文用到的Clinic.xml,本文继续使用这个简单的XML文件作示例)。现在开始吧,启动Delphi 6,在主菜单上选择File | New - Other,然后在仓库中选择XML Data Binding,如图1所示。向导有三个页面。第一页定义XML纲(Schema)或XML文件(本例用Clinic.xml),如图2所示。
在资源输入框内输入XML纲(Schema)或XML文件。“选项”(Options)对话框定义编码选项和数据类型映射关系(Data Type map)。以后我们还会谈到这些选项。向导的第二页显示了树结构和节点数据类型(亦即向导生成了些什么样的代码)。图3可以看到我的XML文件结构。
可以看到XML文件里描述的嵌套节点(ClinicsType与ClinicType)和单节点(String)。这时可以打开选项(Options)对话框(图4),修改编码(比如修改前缀)和数据类型映射。向导的第三页显示生成的相应接口和类。可以把这些结果保存到文件(例如生成Clinic.xdb)。
结果(存储为Clinic.xdb文件)显示如下。我们得到一个ClinicsType类型的Clinics元素,其中包括ClinicType类型的Clinic系列元素。 <?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://www.borland.com/schemas/delphi/6.0/XMLDataBinding">
<xs:element name="Clinics" type="ClinicsType"/>
<xs:complexType name="ClinicsType">
<xs:annotation>
<xs:appinfo xdb:docElement="Clinics"/>
</xs:annotation>
<xs:sequence>
<xs:element name="Clinic" type="ClinicType" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ClinicType">
<xs:sequence>
<xs:element name="Title" type="xs:string"/>
<xs:element name="Date" type="xs:string"/>
<xs:element name="Topics" type="xs:string"/>
</xs:sequence>
<xs:attribute name="No" type="xs:string"/>
</xs:complexType>
</xs:schema>文件同时定义ClinicType类型的Clinic元素包含一系列字符串元素(Title, Date和Topics)。生成代码
向导生成的代码可以直接在应用中使用。不幸的是,Delphi 6有时会产生“非法操作”的出错信息。重新执行一遍,它又能工作了。
以下是生成的代码(Clinic.pas): {****************************************************}
{ }
{ Delphi XML Data Binding }
{ }
{ Generated on: 2001/11/07 00:37:00 }
{ Generated from: D:D6ClinicsrcClinic.xml }
{ Settings stored in: D:D6ClinicsrcClinic.xdb }
{ }
{****************************************************}
unit Clinic;
interface
uses xmldom, XMLDoc, XMLIntf; type { Forward Decls } IXMLClinicsType = interface;
IXMLClinicType = interface; { IXMLClinicsType } IXMLClinicsType = interface(IXMLNodeCollection)
['{06723E03-662D-11D5-81CE-00104BF89DAD}']
{ Property Accessors }
function Get_Clinic(Index: Integer): IXMLClinicType;
{ Methods & Properties }
function Add: IXMLClinicType;
function Insert(const Index: Integer): IXMLClinicType;
property Clinic[Index: Integer]: IXMLClinicType
read Get_Clinic; default;
end; { IXMLClinicType } IXMLClinicType = interface(IXMLNode)
['{06723E04-662D-11D5-81CE-00104BF89DAD}']
{ Property Accessors }
function Get_No: WideString;
function Get_Title: WideString;
function Get_Date: WideString;
function Get_Topics: WideString;
procedure Set_No(Value: WideString);
procedure Set_Title(Value: WideString);
procedure Set_Date(Value: WideString);
procedure Set_Topics(Value: WideString);
{ Methods & Properties }
property No: WideString read Get_No write Set_No;
property Title: WideString read Get_Title write Set_Title;
property Date: WideString read Get_Date write Set_Date;
property Topics: WideString read Get_Topics write Set_Topics;
end; { Forward Decls } TXMLClinicsType = class;
TXMLClinicType = class; { TXMLClinicsType } TXMLClinicsType = class(TXMLNodeCollection, IXMLClinicsType)
protected
{ IXMLClinicsType }
function Get_Clinic(Index: Integer): IXMLClinicType;
function Add: IXMLClinicType;
function Insert(const Index: Integer): IXMLClinicType;
public
procedure AfterConstruction; override;
end; { TXMLClinicType } TXMLClinicType = class(TXMLNode, IXMLClinicType)
protected
{ IXMLClinicType }
function Get_No: WideString;
function Get_Title: WideString;
function Get_Date: WideString;
function Get_Topics: WideString;
procedure Set_No(Value: WideString);
procedure Set_Title(Value: WideString);
procedure Set_Date(Value: WideString);
procedure Set_Topics(Value: WideString);
end; { Global Functions } function GetClinics(Doc: IXMLDocument): IXMLClinicsType;
function LoadClinics(const FileName: WideString): IXMLClinicsType;
function NewClinics: IXMLClinicsType;这里有二个接口类型:IXMLClinicsType和IXMLClinicType;用二个类(TXMLClinicsType和TXMLClinicType)来执行这二个接口。另外还有三个全局函数:GetClinics (获得根元素),LoadClinics (从外部XML文件加载)和NewClinics (在内存生成新文件)。用法
使用生成的Clinic.pas单元是很容易的。跟前一篇文章的做法一样,使用XMLDocument组件(在Inernet标签内)。不过我们不再使用无类型节点了,我们可以调用GetClinics函数获得IXMLClinicsType类型。以下是具体操作过程:在Delphi 6建立一个新的应用(project)
在XML数据绑定向导指引下建立Clinic.pas文件(经过命名存盘 - 译者)
在主窗体上加入一个XMLDocument组件,其FileName属性为Clinic.xml
在主窗体的OnCreate事件中加入以下代码:
procedure TForm1.FormCreate(Sender: TObject);
var
Clinics: IXMLClinicsType;
begin
Clinics := GetClinics(XMLDocument1);
end;把Clinics变量放到主窗体中是很有用的,这样就可以在主窗体运行期间使用Clinics接口。使用IXMLClinicsType变量类型要比以前使用普通XMLDocument组件方便多了。现在可以通过Get_Clinic方法来获得各个Clinic元素,还可以在特定位置插入新的Clinic元素。用Clinics.Clinic可以获得节点元素,用Getter和Setter方法可以得到或设置元素值。现在可以直接访问No, Title, Date, Topics等属性了:
procedure TForm1.ButtonGetClick(Sender: TObject);
var
Clinic: IXMLClinicType;
begin
Clinic := Clinics.Clinic[0];
EditNo.Text := Clinic.No;
EditTitle.Text := Clinic.Title;
EditDate.Text := Clinic.Date;
EditTopics.Text := Clinic.Topics
end;可以在Clinic.pas中看到,Getter和Setter是方法而不是属性(实际上,我始终认为使用属性更清楚些)。但是Delphi 6让你看到的却是属性描述而不是方法本身(Delphi 6的另一个受欢迎的优点)。将上面这段代码与前一篇文章使用的方法相比较,就能感到操作方便多了。下面的例子在XML树的末尾加入一个节点:
procedure TForm1.ButtonAddClick(Sender: TObject);
begin
with Clinics.Add do
begin
No := '2001-2-8; // 8th Clinic of the 2nd series of 2001
Title := 'Special Kylix 2 Clinic';
Date := '2001/12/21';
Topics := 'Kylix 2 New Features'
end
end;如果没有把XMLDocument组件的AutoSave设置为真,可以用以下方法保存更动结果:
procedure TForm1.FormDestroy(Sender: TObject);
begin
XMLDocument1.SaveToFile;
end;
我直接用的IXMLNode访问,发现一个问题,不得其解,如下:
var
Root, Head, Body : IXMLNode;
begin
Root:= XDoc.DocumentElement;
Head:= Root.ChildNodes[0]; //包头节点
Body:= Root.ChildNodes[1]; //包体节点
Head.ChildNodes[0].ChildNodes[1].Text:= '0000'; //这样可以
Body.ChildNodes[0].ChildNodes['Name'].Text:= 'Feng'; //这样会填加一个新节点,真是奇怪,百思不得其解
只要稍作设置(设置FileName为clinics.xml和将doAutoSave置为真),就可以激活TXMLDocument组件。激活之后,就可以遍历节点,读取和编辑数据。
现在我们可以在XMLDocument里访问各个节点(IXMLNode),递归访问各节点的子节点。例如,可以用一个按钮来获取第一个节点的元素值并将结果写入Memo:
procedure TForm1.Button1Click(Sender: TObject);
var
Clinic: IXMLNode;
begin
Clinic := XMLDocument1.DocumentElement.ChildNodes[0];
Memo1.Lines.Clear;
Memo1.Lines.Add(Clinic.ChildNodes['Title'].Text);
Memo1.Lines.Add(Clinic.ChildNodes['Date'].Text);
Memo1.Lines.Add(Clinic.ChildNodes['Topics'].Text)
end;增加索引指针可以访问其它节点。下面的例子用"current"作索引,通过循环增加"current"的值来遍历节点。我用try-except来防止循环出界。
procedure TForm1.Button2Click(Sender: TObject);
var
Clinic: IXMLNode;
begin
Inc(current);
try
Clinic := XMLDocument1.DocumentElement.ChildNodes[current];
Memo1.Lines.Clear;
Memo1.Lines.Add(Clinic.ChildNodes['Title'].Text);
Memo1.Lines.Add(Clinic.ChildNodes['Date'].Text);
Memo1.Lines.Add(Clinic.ChildNodes['Topics'].Text);
except
on E: Exception do
Memo1.Lines.Add(E.Message)
end
end;除了遍历节点之外,还可以修改子节点的值。下面的代码将第一个节点的标题值加上一个"HOT"前缀。
procedure TForm1.Button1Click(Sender: TObject);
var
Clinic: IXMLNode;
begin
current := 0;
Clinic := XMLDocument1.DocumentElement.ChildNodes[current];
Memo1.Lines.Clear;
Clinic.ChildNodes['Title'].Text := 'HOT: ' + Clinic.ChildNodes['Title'].Text;
Memo1.Lines.Add(Clinic.ChildNodes['Title'].Text);
Memo1.Lines.Add(Clinic.ChildNodes['Date'].Text);
Memo1.Lines.Add(Clinic.ChildNodes['Topics'].Text);
end;还可以增删节点。下面的代码增加一个子节点并赋予缺省值:
procedure TForm1.Button1Click(Sender: TObject);
var
Clinic: IXMLNode;
begin
Clinic := XMLDocument1.DocumentElement.AddChild('Clinic');
Clinic.ChildNodes['Title'].Text := 'Title';
Clinic.ChildNodes['Date'].Text := 'Date';
Clinic.ChildNodes['Topics'].Text := 'Topics';
end;