Managing JSON Array format in MQL4 script

10.5k views Asked by At

I would need to get data from inside a JSON Array.
I use a call to WebRequest() function to get an order list from my db, thru a nodejs(api) and then I got the following JSON-data format e.g:

[{"orderid":       123556,
  "ordertype":     0,
  "ordercurrency": "EURUSD",
  "orderdt":       "2016-12-03 03:00:00"
  },
 {"orderid":       123457,
  "ordertype":     0,
  "ordercurrency": "GBPUSD",
  "orderdt":       "2016-12-03 03:15:00"
  }
 ]

Any idea how to transform it to a normal array in order to manage data?

Thank you.

/Koul

4

There are 4 answers

0
Dave On BEST ANSWER

JSON Serialization and Deserialization library works pretty well. You can include it and finish your task within a minute or get an inspiration from its code.

https://www.mql5.com/en/code/13663

https://www.mql5.com/en/forum/65320

Let's assume you have the JSON data you pasted in a string variable named data.

#include <JAson.mqh>

// Object
CJAVal json;

// Load in and deserialize the data
json.Deserialize(data);

// Try to access the data elements
Alert(json["orderid"].ToInt());
Alert(json["ordercurrency"].ToStr());
3
user3666197 On

How?
Easy:

JSON-format is a "string-ified" representation of data-elements, put into a common container, be it a uchar[] or a string on the MQL4 side.

So, let's create a JSON-parser, coherent with the subset of the standard JSON-format syntax rules.

1) Search for all db-output "row"-s ( encapsulated in {...} )

2) Decode all db-output "column"-s ( encoded in ( known ) "KEY":VALUE pairs )

3) Store decoded values into any kind of target representation,

int    orderIdNoARRAY[];
int    orderTypeARRAY[];
string orderCurrARRAY[];
string orderDateARRAY[];
int    anArrayStackPTR = 0
...
orderIdNoARRAY[anArrayStackPTR] = aDecodedOrderID;    // 123556
orderTypeARRAY[anArrayStackPTR] = aDecodedOrderTYPE;  // 0
orderCurrARRAY[anArrayStackPTR] = aDecodedOrderCURR;  // "EURUSD"
orderDateARRAY[anArrayStackPTR] = aDecodedOrderDATE;  // "2016-12-03 03:00:00"

or

#define oID   0
#define oTYPE 1
#define oCCY  2
#define oDATE 3

string stringDataFromJSON[10000,4];
int    anArrayStackPTR = 0
...
stringDataFromJSON[anArrayStackPTR,oID]   = (string)aDecodedOrderID;      // 123556
stringDataFromJSON[anArrayStackPTR,oTYPE] = (string)aDecodedOrderTYPE;    // 0
stringDataFromJSON[anArrayStackPTR,oCCY]  = (string)aDecodedOrderCURR;    // "EURUSD"
stringDataFromJSON[anArrayStackPTR,oDATE] = (string)aDecodedOrderDATE;    // "2016-12-03 03:00:00"

or

struct        aDB_RECORD{
       int    aDB_oID;
       int    aDB_oTYPE;
       string aDB_oCCY;
       string aDB_oDATE;
};

aDB_RECORD anArrayOfSTRUCTs[];
int    anArrayStackPTR = 0
...
anArrayOfSTRUCTs[anArrayStackPTR].aDB_oID   = aDecodedOrderID;    // 123556
anArrayOfSTRUCTs[anArrayStackPTR].aDB_oTYPE = aDecodedOrderTYPE;  // 0
anArrayOfSTRUCTs[anArrayStackPTR].aDB_oCCY  = aDecodedOrderCCY;   // "EURUSD"
anArrayOfSTRUCTs[anArrayStackPTR].aDB_oDATE = aDecodedOrderDATE;  // "2016-12-03 03:00:00"

Yes,
it is that easy!

0
user20972358 On
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <JAson.mqh>

int OnInit()
  {
  
CJAVal data;
string aCookieHOLDER = NULL,
          aHttpHEADERs;
   char   postBYTEs[],
          replBYTEs[];
      
      
   int    aRetCODE;
   
   string aTargetURL ="https://apitester.ir/api/Categories";
                    /*  to enable access to the URL-> pointed server,
                        you should append "https://api.myjson.com/bins/56z28"
                        to the list of allowed URLs in
                        ( Main Menu -> Tools -> Options, tab "Expert Advisors" ):
                        */
   ResetLastError();                     
   int    aTIMEOUT = 5000;              
                                       
   aRetCODE = WebRequest("GET",
                          aTargetURL,
                          aCookieHOLDER,
                          NULL,
                          aTIMEOUT,
                          postBYTEs,
                          0,
                          replBYTEs,
                          aHttpHEADERs
                          );
                          
   if ( aRetCODE == NULL )             
   {    Print( "Error in WebRequest(). Error code  = ", GetLastError() );    
     }
   else
   {  
   
    
   string k=data.GetStr(replBYTEs,0,replBYTEs.Size());

  data.Deserialize(k,0);
 Comment(data.m_e[0].m_e[1].m_sv);
    
   }
   return(INIT_SUCCEEDED);
  }

//after Deserialize you access any of row in json with m_e[0 to total size of objects] and access to any items of object with m_e[0 to count of keys]

0
Vivazzi On

Yes, JAson - JSON Serialization and Deserialization library works is good popular library: https://www.mql5.com/en/code/13663
https://www.mql5.com/en/forum/65320

I wrote documentation with more details (different from https://www.mql5.com/en/code/13663) and added unit tests:
https://github.com/vivazzi/JAson.

It may be useful for you.