Delphi 6 (Enterprise and up) has an XML Data Binding Wizard. This very nice tool was described in several books and articles. Almost all sources are very brief and do not cover all interesting features.
Below are the result of my research and experiments with Delphi XML data binding tool. It is done in the form of a small working project.
1. The address book has a title <Remark> and contains several persons:
<Addressbook> <Remark>Main Address Book</Remark> + <Person> + <Person> + <Person> </Addressbook>2. Each person has First, Middle and Last names and can have several addresses (home, work, etc.):
- <Person> <FirstName>John</FirstName> <Middle>N.</Middle> <LastName>Doe</LastName> <Birthday>12/12/1956</Birthday> + <Address AddrType="Home"> + <Address AddrType="Work"> </Person>3. Each address includes the following information:
- <Address AddrType="Home"> <Title>Mr.</Title> <Position /> <Street>1234 First Ave</Street> <Street>Apt #56</Street> <Town>Bigtown</Town> <County>Somecounty</County> <State>XY</State> <PostalCode>12345</PostalCode> <Country /> <Phone>(234)123 4567</Phone> <Phone>(234)123 7890 mobile</Phone> <Fax /> <Email>john@doe.com</Email> <URL>www.doe.com/john.html</URL> <Comment>No comment</Comment> <Modified>02/02/2002</Modified> </Address>
<?xml version="1.0" encoding="UTF-8"?>
<Addressbook>
<Remark>Main Address Book</Remark>
<Person>
<FirstName>John</FirstName>
<Middle>N.</Middle>
<LastName>Doe</LastName>
<Birthday>12/12/1956 </Birthday>
<Address AddrType="Home">
<Title>Mr.</Title>
<Position></Position>
<Street>1234 First Ave</Street>
<Town>Bigtown</Town>
<County>Somecounty</County>
<State>XY</State>
<PostalCode>12345</PostalCode>
<Country></Country>
<Phone>(234)123 4567</Phone>
<Phone>(234)123 7890 mobile</Phone>
<Fax></Fax>
<Email>john@doe.com</Email>
<URL>www.doe.com/john.html</URL>
<Comment>No comment</Comment>
<Modified>02/02/2002</Modified>
</Address>
<Address AddrType="Work">
<Title>Dr.</Title>
<Position>Professor</Position>
<Street>2345 Main Str</Street>
<Street>Building # 5</Street>
<Town>Bigtown</Town>
<County></County>
<State>XY</State>
<PostalCode>12346</PostalCode>
<Country>U.S.A.</Country>
<Phone>(234)123 7811 ext 321</Phone>
<Fax>(234)123 7810</Fax>
<Email>johndoe@xyz.edu</Email>
<URL>www.xyz.edu/johndoe.html</URL>
<Comment></Comment>
<Modified>02/02/2002</Modified>
</Address>
</Person>
<Person>
<FirstName>Ann</FirstName>
<Middle></Middle>
<LastName>Smith</LastName>
<Birthday>12/24/1965 </Birthday>
<Address AddrType="Home">
<Title>Ms.</Title>
<Position></Position>
<Street>2346 Second Ave</Street>
<Town>Bigtown</Town>
<County></County>
<State>XY</State>
<PostalCode>12345</PostalCode>
<Country></Country>
<Phone>(234)123 2222</Phone>
<Email>annsmith@yahoo.com</Email>
<Comment>My girlfriend</Comment>
<Modified>02/02/2002</Modified>
<Fax></Fax>
<URL></URL>
</Address>
</Person>
</Addressbook>
2. In the Delphi IDE go > File > New > Other > New > XML Data
Binding
3. In XML Data Binding Wizard

3, Next > Review of generated interfaces > Finish > save the Unit1 as uAddrBookXML. The corresponding XML schema is saved in AddrBook.xdb file. It can be used later instead of AddrBook.xml
4. The generated unit can be further modified. The following modifications sometimes are necessary and useful:
procedure Delete(Index: integer);then you do not need to implement it because the base class TXMLNodeCollection already has the Delete method.
property Items[Index: Integer]: IXMLPersonType read GetItem; default;It should be replaced with
property Items[Index: Integer]: WideString read GetItem write SetItem; default; . . . procedure TXMLString_List.SetItem(Index: Integer; const Value: WideString); begin List[Index].NodeValue := Value; end;
function GetAddressbook(Doc: IXMLDocument): IXMLAddressbookType; function LoadAddressbook(const FileName: WideString): IXMLAddressbookType; function NewAddressbook: IXMLAddressbookType;The first one creates the AddressBook object (interface) from IXMLDocument, but creation from a string (XML text) is missing. Matt Peebles in http://codecentral.borland.com/id=17805 suggested to overload Get . . . (in our case would be GetAddressbook)
function GetAddressbook(Doc: IXMLDocument): IXMLAddressbookType; overload; function GetAddressbook(DocString: string): IXMLAddressbookType; overload;with the following implementation
function GetAddressbook(DocString: string): IXMLAddressbookType;
begin
Result := LoadXMLData(DocString).GetDocBinding('Addressbook', TXMLAddressbookType) as IXMLAddressbookType;
end;
The latter modification was not used in the current project.
Almost all books and articles recommend to use the XMLDocument component. This component (XMLDocAddr in this case) really simplifies loading and saving the XML data. However, it is not necessary to use it at all. For example, the data can be loaded from a string using the overloaded GetAddressbook function. The property XMLDocAddr.XML.Text corresponds to the property AddrBook.XM, and you can directly exchange data between them.
The project demonstrates the power of data binding objects. First, you can create, delete and modify the nodes at all levels (in this case Persons, Addresses, Phones, Streets). Second, the objects make navigation through documents really easy.
This project was developed for education purpose only (self-education primarily). The included demo program is not a commercial product. The author is not responsible for any other use of them. Both the source code and the demo can be downloaded here. You can freely use them. Comments and remarks are welcome.
Nikolai Shokhirev, nikolai@shokhirev.com
|
|
Please e-mail me at nikolai@shokhirev.com |
ŠNikolai V. Shokhirev, 2002