Mega Code Archive

 
Categories / Delphi / Ide Indy
 

Connecting WDSL service in Delphi

Title: Connecting WDSL service in Delphi Question: I have a web server application running on Linux (written in PHP/NUSOAP). I am currently working on a client application with Delphi 2005, the client is supposed run on Windows environment to call the web service (wsdl) on the remote server. The web service requires to input an associated array (ie. username, password) - it seems to me that Delphi does NOT support associated array, therefore I have defined a class for it in Delphi - however, I got the following error - on Incompatible type [Error] loginclient.pas(70): E2010 Incompatible types: 'loginserver.UserDetail' and 'loginclient.UserDetail' [Fatal Error] login.dpr(6): F2063 Could not compile used unit 'loginclient.pas' Answer: I found a possible solution via this web site, but the links are no longer valid. http://www.undu.com/Articles/020604.html Hashes (Associative Arrays) in Delphi Author: Ciaran McCreesh - keesh@users.sf.net A hash (properly known as an associative array) is a bit like an array, but instead of having an ordinal (integer, char and so on) index, each item is identified by a string. To allow items to be found quickly, a technique known as hashing (hence the name hash) is used. (see footnote 1). Delphi doesn't have native support for this kind of data structure. However, a number of classes implementing this functionality are available. Here I'll focus on my own general-purpose implementation-- I am familiar with it, and, unlike many other libraries, it doesn't rely upon casting. It works in Delphi 5 and later; it should also work in Kylix with little or no modification. To begin with, download the latest version of the libraries. Unzip the file into your Delphi lib directory, or wherever you usually install libraries. Because the components provided are non-visual, there is no need to install a package. This library provides (so far) a base THash component, plus three descendants -- TStringHash (for storing strings), TIntegerHash (for storing integers) and TObjectHash (for storing instances of TObject). There are instructions on how to create your own descendants in the source. We'll use TStringHash for our examples, but the others work in the same way. We create and destroy instances of TStringHash in the usual way. In case anything goes wrong, we'll wrap the code in a try..finally block. Procedure Example; var h: TStringHash; begin h := TStringHash.Create; try { Do some things with h } finally h.Free; end; end; We can assign to an item in the hash in just the same way as we would an array (see footnote 2): h['mykey'] := 'Some Value'; h[myStringVar] := 'Another value'; h['mykey'] := 'Now we overwrite the mykey value'; We can also read items this way: myStringVar := h['mykey']; if (h['foo'] = 'bar') then { do something }; If we try to access a key which doesn't exist, THash throws an exception. We can test whether a key exists using the Exists method: if (h.Exists('somevalue')) then { do something }; We can also delete a key: h.Delete('mykey'); Renaming a key is also possible. If we rename a key to a name that already exists, that key is overwritten. h.Rename('oldname', 'newname'); We can find out how many items are in the hash with the ItemCount property: MessageDlg(Format('There are %d item(s) in the hash.', [h.ItemCount]), mtInformation, [mbOK], 0); Iterating over the items in a hash is more interesting. One major difference between arrays and hashes is contiguity. In an array, we have a certain number of items which are stored one after another with no gaps. A hash is not like this. (see footnote 3) For this reason, we can't use a for loop. Technically, our hash is not even aware of how many items it contains; it must work it out when asked. However, it can still iterate over its own items. To begin iteration, we call the Restart method. This is like initializing our loop counter variable at the start of an array iteration. We then call the .Next method to get the next (first) item in the hash. This is a boolean function; it returns true if successful, or false if there are no items left. We can access the current key using the CurrentKey function. h.Restart; while (h.Next) do myListBox.Items.Add(Format('Key "%s" has value "%s".', [ h.CurrentKey, h[h.CurrentKey]])); One important note: you must not add items to the hash or rename or delete items during an iteration. After carrying out one of these operations, you must call Restart and start again. This is another big difference between arrays and hashes -- with an array, we know where an item is; with a hash, the internal data structure can change dramatically. The TObjectHash deserves a brief commentary. Like a TCollection, it will automatically free its contents when destroyed, when an item is deleted and so on. Keep this in mind when coding with it. Feel free to play around with, modify, use and redistribute the library. I welcome feedback, bug reports (yep, even I make mistakes occasionally :) ), suggestions, patches and so on. I'm currently writing a second article explaining more about hashing (the theory rather than the implementation); if you're wanting to do something a bit more complex than a straight flat hash, this might be of use to you. Please post some comments or advice if possible.