Read an xml file as text in mq5

 

I have an mql4 script that reads an xml file and display it as text.

int FileHandle=FileOpen(xmlFileName,FILE_BIN|FILE_READ);
ulong size=FileSize(FileHandle);
sData=FileReadString(FileHandle,(int)size);


Below is the result:


However when run in mq5, the data is not in text mode. I need help please. Below is the outcome on mq5.



 
Oladimeji Ogunseye: I have an mql4 script that reads an xml file and display it as text. Below is the result: However when run in mq5, the data is not in text mode. I need help please. Below is the outcome on mq5.

You are opening the file as binary content ("FILE_BIN"). Open and read it as a text file ("FILE_TXT") instead, using either "ANSI" or "UNICODE" (File Opening Flags).

Documentation on MQL5: Constants, Enumerations and Structures / Input/Output Constants / File Opening Flags
Documentation on MQL5: Constants, Enumerations and Structures / Input/Output Constants / File Opening Flags
  • www.mql5.com
File Opening Flags - Input/Output Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Fernando Carreiro:

You are opening the file as binary content ("FILE_BIN"). Open and read it as a text file ("FILE_TXT") instead, using either "ANSI" or "UNICODE" (File Opening Flags).


Thank you  Fernando Carreiro


I have tried reading as TXT before I posted the question. The ANSI option does not give a complete result. These are the results


Using TXT and ANSI, only a fragment of the text is read. The remaining is ignored.

int FileHandle=FileOpen(xmlFileName,FILE_READ|FILE_TXT|FILE_ANSI);
ulong size=FileSize(FileHandle);
sData=FileReadString(FileHandle,(int)size);



Using TXT and UNICODE 

The result is still bin

int FileHandle=FileOpen(xmlFileName,FILE_READ|FILE_TXT|FILE_UNICODE);
ulong size=FileSize(FileHandle);
sData=FileReadString(FileHandle,(int)size);





I have also tried other combination with similar result.


int FileHandle=FileOpen(xmlFileName,FILE_TXT|FILE_ANSI,CP_UTF8);

 

Oladimeji Ogunseye: I have tried reading as TXT before I posted the question. The ANSI option does not give a complete result. These are the results

Using TXT and ANSI, only a fragment of the text is read. The remaining is ignored.

int FileHandle=FileOpen(xmlFileName,FILE_READ|FILE_TXT|FILE_ANSI);
ulong size=FileSize(FileHandle);
sData=FileReadString(FileHandle,(int)size);

Using TXT and UNICODE 

The result is still bin

int FileHandle=FileOpen(xmlFileName,FILE_READ|FILE_TXT|FILE_UNICODE);
ulong size=FileSize(FileHandle);
sData=FileReadString(FileHandle,(int)size);
I have also tried other combination with similar result.
int FileHandle=FileOpen(xmlFileName,FILE_TXT|FILE_ANSI,CP_UTF8);

You are only showing your code for opening and reading the file and not how you are outputting it.

So please provide the following;

  1. The FFCal XML file that you are reading (attach file to the post).
  2. An example MQL4 source code that reads and displays the file contents as you have shown in screenshots so we can analyse it (use the "</>" icon).

Please make sure to use the Alt-S or the "</>" icon in your posting toolbar when inserting code. Don't just past it into the middle of your normal text.


 
Fernando Carreiro:

You are only showing your code for opening and reading the file and not how you are outputting it.

So please provide the following;

  1. The FFCal XML file that you are reading (attach file to the post).
  2. An example MQL4 source code that reads and displays the file contents as you have shown in screenshots so we can analyse it (use the "</>" icon).

Please make sure to use the Alt-S or the "</>" icon in your posting toolbar when inserting code. Don't just past it into the middle of your normal text.


Below are the codes:


MQ4 CODE

xmlFileName="ffcal_week_this.xml";
int FileHandle=FileOpen(xmlFileName,FILE_BIN|FILE_READ);
ulong size=FileSize(FileHandle);
sData=FileReadString(FileHandle,(int)size);
Print("sdate me: ",sData);


MQ5 CODE

xmlFileName="ffcal_week_this.xml";
int FileHandle=FileOpen(xmlFileName,FILE_READ|FILE_TXT|FILE_ANSI);
ulong size=FileSize(FileHandle);
sData=FileReadString(FileHandle,(int)size);
Print("sdate me: ",sData);


Files:
 
Oladimeji Ogunseye: Below are the codes

The XML file you provided has multiple lines, so please remember that when reading a text file, the function "FileReadString" will only read one line up to the LF (Line-feed, 0x0A) character. It will not read the entire file, so don't use a size parameter. Instead you have to keep reading the file text line by line until the end of the file, and build up your data.

Continue to use "FILE_TXT|FILE_ANSI", since the source is using "windows-1252" coding. The text that is read is then converted to unicode internally as MQL5 strings are unicode.

 
Fernando Carreiro:

The XML file you provided has multiple lines, so please remember that when reading a text file, the function "FileReadString" will only read one line up to the LF (Line-feed, 0x0A) character. It will not read the entire file, so don't use a size parameter. Instead you have to keep reading the file text line by line until the end of the file, and build up your data.

Continue to use "FILE_TXT|FILE_ANSI", since the source is using "windows-1252" coding. The text that is read is then converted to unicode internally as MQL5 strings are unicode.

Thank you so much. I was able to get the pointer to read each line. However I want to ask is there any limit to the number of string variables to add.
I have 912 lines read from the text. When added together, I am only able to add some and not all of the entire length of line.

I tried "StingAdd" and "StringConcatenate" and also the use of "+" to add the lines together. AM not able to add all.


Is there a limit to the number of string variables I can add together.

ulong pos[]; 
    int   size; 
   
     string sData ="";
       
    int file_handle=FileOpen(xmlFileName,FILE_READ|FILE_TXT|FILE_ANSI);
    if(file_handle!=INVALID_HANDLE) 
     { 
      GetStringPositions(file_handle,pos); 
      size=ArraySize(pos); 
      size=912;
      
    for(int g=0;g<size;g++)
       {
         if(FileSeek(file_handle,pos[g],SEEK_SET)==true) 
           { 
            
            StringAdd(sData,FileReadString(file_handle));
           //StringConcatenate(sData,sDatas,FileReadString(file_handle));
           } 
        }
        
        
       Print(sData);
    
 
Oladimeji Ogunseye:

Thank you so much. I was able to get the pointer to read each line. However I want to ask is there any limit to the number of string variables to add.
I have 912 lines read from the text. When added together, I am only able to add some and not all of the entire length of line.

I tried "StingAdd" and "StringConcatenate" and also the use of "+" to add the lines together. AM not able to add all.

Is there a limit to the number of string variables I can add together.

In the past, I also ran into size limits when concatenating strings together. I don't know if that was ever fixed. I suspect it was not.

As an option, consider reading the lines into an array of strings, one array element per line.

Another option is to read the data as a char array using FileReadArray() but with the FILE_BIN property, but the result will not be a string. This would also be the case if you opted to read the XML data directly from the web source via WebRequest() which would also end up in a char array. This obviously is not a string and you would have to handle the char array differently.

 
Fernando Carreiro:

In the past, I also ran into size limits when concatenating strings together. I don't know if that was ever fixed. I suspect it was not.

As an option, consider reading the lines into an array of strings, one array element per line.

Another option is to read the data as a char array using FileReadArray() but with the FILE_BIN property, but the result will not be a string. This would also be the case if you opted to read the XML data directly from the web source via WebRequest() which would also end up in a char array. This obviously is not a string and you would have to handle the char array differently.

Thank you a lot.

Going by the firs option: " As an option, consider reading the lines into an array of strings, one array element per line."

I have earlier tried it; having an array of strings. Adding all the array elements seems to exceed the maximum capacity sting can allow.

I tried "StingAdd" and "StringConcatenate" and also the use of "+" to add the lines together. Only a portion of the array elements is added.

Is there any way to add the string array.


 
An inefficient way could be using StringFormat().

But I don't know if this will overcome the limitation of string variable.
Reason: