1

Im trying to load a remotely hosted XML file using Delphi. I am assuming that I can load it from a Stream. I have a FetchRemote class that fetches the URL stream:

function TFetchRemote.StreamFromUrl(filename : String) : TMemoryStream;
var
  memStream : TMemoryStream;
  http : TIdHttp;
begin
  http := TIdHttp.Create();
  memStream := TMemoryStream.Create;
  http.Get(url + filename, memStream);
  Result := memStream;
end;

I am trying to use the returned memory stream to load the remote XML:

function TFetchRemoteXML.XMLFromUrl(filename : string) : TXMLDocument;
var
  memStream : TMemoryStream;
begin
  memStream := fetchRemote.StreamFromURL(filename);
  try
    memStream.Position := 0;
    Result := TXMLDocument.LoadFromStream(memStream);
  finally
    memStream.Free;
  end;
end;

The error that I am getting when I try compiling is: (On the Result return line)

[dcc32 Error] FetchRemoteXML.pas(31): E2076 This form of method call only allowed for class methods or constructor

I have a similar class/method to fetch a remote Bitmap and it works fine. I just can't see what I am doing wrong to fetch the XML. I have tried following some examples in the Delphi help, and tried getting some hints from this StackOverflow question but no luck. Any suggestions would be greatly appreciated, I'm new to Delphi (coming from a Ruby background). I am using RAD Studio XE 5.

Thanks in advance!

Community
  • 1
  • 1
jbmoon
  • 129
  • 1
  • 11
  • Your code indicates you might not be aware of object lifetime management rules in Delphi. You might want to take a bit of time and learn that now. – Warren P Nov 28 '13 at 01:55

1 Answers1

4

The LoadFromStream method is an instance method. Which means that you have to instantiate an instance of TXMLDocument and call LoadFromStream on that.

Result := TXMLDocument.Create(Owner);
Result.LoadFromStream(...);

You'll need to supply an owner for the object as described in the documentation for the constructor.

Or pass nil to the constructor and switch to IXMLDocument instead of TXMLDocument.

function TFetchRemoteXML.XMLFromUrl(filename : string) : IXMLDocument;
var
  memStream : TMemoryStream;
begin
  memStream := fetchRemote.StreamFromURL(filename);
  try
    Result := TXMLDocument.Create(nil);
    Result.LoadFromStream(memStream);
  finally
    memStream.Free;
  end;
end;
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • I've tried calling `xml := TXMLDocument.Create(nil); Result := xml.LoadFromStream(memStream);` but it returns a different error message: [dcc32 Error] FetchRemoteXML.pas(33): E2010 Incompatible types: 'TXMLDocument' and 'procedure, untyped pointer or untyped parameter' – jbmoon Nov 26 '13 at 15:00
  • That won't work. Compiler explains why not. Do what I say in the answer. – David Heffernan Nov 26 '13 at 15:02