* * *

Author Topic: How to read a XMLstring from an API as a stream  (Read 673 times)

arneolav

  • Full Member
  • ***
  • Posts: 112
    • ElTranslador
How to read a XMLstring from an API as a stream
« on: March 30, 2018, 11:08:49 pm »
From an external API I'm getting a XML file using Synapse, Oauth1/GetBody.
The file is saved to disk (as a string,  Textfile) and then read the diskfile:

Using TXMLConfig:
var  iDoc    : TXMLDocument;
  Child,  gChild:TDOMNode; 
...
 ReadXMLFile(iDoc,  FilePath);
      Child := iDoc.DocumentElement.FirstChild;
      while Assigned(Child) do
      begin  .....

This works great, but to avoid use of diskfile  I 'v spend some hours to figure out how to read the input from the API as a stream.
I suppose I have to replace the "ReadXMLFile"  but can't find "how to".
May be somebody can give me an idea.
« Last Edit: March 31, 2018, 09:37:48 pm by arneolav »
Win XP, Win7, Win 10 win64 , Lazarus 1.8.2
Delphi/DevExpress

molly

  • Hero Member
  • *****
  • Posts: 2345
Re: How to read a file from an API as a stream
« Reply #1 on: March 30, 2018, 11:44:06 pm »
var
  stream: Tmemorystream;
...
  stream :=Tmemorystream.create;
  // use whatever you want to fill the stream, LoadFromfile as example
  stream.LoadFromFile(FilePath)
  ReadXMLFile(iDoc,  stream);
  Child := iDoc.DocumentElement.FirstChild;
  stream.free;
  // etc.
...

See xmlread.pp:
Quote
procedure ReadXMLFile(out ADoc: TXMLDocument; const AFilename: String); overload;
procedure ReadXMLFile(out ADoc: TXMLDocument; var f: Text); overload;
procedure ReadXMLFile(out ADoc: TXMLDocument; f: TStream); overload;
procedure ReadXMLFile(out ADoc: TXMLDocument; f: TStream; const ABaseURI: String); overload;

arneolav

  • Full Member
  • ***
  • Posts: 112
    • ElTranslador
Re: How to read a XMLstring from an API as a stream
« Reply #2 on: March 31, 2018, 12:38:44 pm »
Hi molly!
Thanks for your insperation!
I'v been away from Lazarus som period and my head is "emty" of "lazarus stuff".

Here is my "working" solution:

function ConvXMLstring(const XMLstr: string)          // String from the API
var
  iDoc    : TXMLDocument;
  Child, gChild:TDOMNode;
  AStream: TStringStream;
begin
  AStream := TStringStream.Create(XMLstr);          { assign the XMLstring to the stream}

  try
    if Assigned(AStream) then
      ReadXMLFile(iDoc, AStream);                   { read the stream, the XMLstring }
      Child := iDoc.DocumentElement.FirstChild;     {Get first child }

  while Assigned(Child) do ....


As a help for others, here is a more complete example:
« Last Edit: March 31, 2018, 09:38:15 pm by arneolav »
Win XP, Win7, Win 10 win64 , Lazarus 1.8.2
Delphi/DevExpress

edgarrod71

  • New member
  • *
  • Posts: 22
Re: How to read a XMLstring from an API as a stream
« Reply #3 on: April 24, 2018, 10:50:13 am »
Molly is ok, but here's another option, instead of loading it to the Stream, we can load it directly from the TXMLDocument, and paste it to the Stream, so we can use the stream with different controls using only memory (so it'll be faster).

Code: Pascal  [Select]
  1. const archivo='c:\where_the_file_is.xml';
  2.     [...]
  3.     if assigned(cStream) then
  4.         FreeAndNil(cStream);
  5.  
  6.       cStream := TStringStream.Create('', CP_UTF8);
  7.       ReadXMLFile(cDoc, archivo);
  8.       WriteXML(cDoc, cStream);
  9.       cStream.Seek(0, soBeginning);
  10.       try
  11.         Memo2.Clear;
  12.         Memo2.Lines.LoadFromStream(cStream);
  13.       except
  14.         on EFOpenError do
  15.           ;  /// swallow the error...
  16.       end;
  17.       cNodo := cDoc.FirstChild;
  18.       Memo1.Lines.Clear;
  19.       Memo1.Lines.AddText(cDoc.DocumentElement.TextContent);
  20.       [...]
  21.  

arneolav

  • Full Member
  • ***
  • Posts: 112
    • ElTranslador
Re: How to read a XMLstring from an API as a stream
« Reply #4 on: April 24, 2018, 12:32:47 pm »

Code: Pascal  [Select]
  1.  
  2.     if assigned(cStream) then    
  3.         FreeAndNil(cStream);                  <---  Got an error on this
  4.    
  5.    if assigned(cStream) then cStream := nil; <---- This compile and run OK
  6.  
  7.  
Win XP, Win7, Win 10 win64 , Lazarus 1.8.2
Delphi/DevExpress

arneolav

  • Full Member
  • ***
  • Posts: 112
    • ElTranslador
Re: How to read a XMLstring from an API as a stream
« Reply #5 on: April 24, 2018, 12:54:09 pm »
I ended up with same solution as shown by edgarrod71

Code: Pascal  [Select]
  1. // To make it more simple I tried to get the string direct from the API GetBody:
  2. AStream := TStringStream.Create(Utf8ToAnsi(FConnect.GetBody));   <-- did not work
  3.  
  4. // so I have to pass the recieved string to a function or procedure:
  5.  
  6.  .....   ReadAPIstring(FConnect.GetBody);    
  7.  
  8. function ReadAPIstring(Const XMLstring: string);  
  9. var  AStream: TStringStream;
  10. begin
  11.     if assigned(AStream) then AStream := nil;
  12.     AStream := TStringStream.Create(Utf8ToAnsi(XMLstring));
  13. ......
  14.  
Win XP, Win7, Win 10 win64 , Lazarus 1.8.2
Delphi/DevExpress

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus