Libraries: JSON Serialization and Deserialization (native MQL) - page 14

 

The library is very useful. But I encountered that when serialising values of double type there is a strong loss of precision.

Example:

double minutes_open[] = {0.95347, 0.95317, 0.95324}

for (int i=0; i<ArraySize(minutes_open); ++i) jv["minutes_open"].Add(minutes_open[i]);

After serialisation I get:

"minutes_open":[9.53e-01,9.53e-01,9.53e-01]

I.e. the last 2 significant characters are simply lost and all values in the array become simply equal to each other. As a result, all the calculations based on this data go in vain....

In the end I got round it by converting array values into string.

Документация по MQL5: Основы языка / Типы данных / Приведение типов
Документация по MQL5: Основы языка / Типы данных / Приведение типов
  • www.mql5.com
Приведение типов - Типы данных - Основы языка - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 

Hi there!

Documentation of JAson library is not full at this site. I wrote documentation with more details and added unit tests: https://github.com/vivazzi/JAson. It may be useful for someone.

Add i created issue that has description of bug of using inner Json (CJAVal object): https://github.com/vivazzi/JAson/issues/1.

CJAVal object is not correctly assigned to another CJAVal object as object:

CJAVal data;

// simple structure
data["a"] = 12;

// nested structure
CJAVal nested_data;
nested_data["k1"] = 7;
nested_data["k2"] = "baz";

data["b"] = nested_data;

Print(data["b"]["k1"].ToInt());  // 0 instead of 7
Print(data["b"]["k2"].ToStr());  // "" instead of "baz"
Print(data.Serialize());  // {"a":12,"":{"k1":7,"k2":"baz"},"b":{}} instead of {"a":12,"b":{"k1":7,"k2":"baz"}}

As workaround, you need use Set() method:

data["b"].Set(nested_data);

Print(data["b"]["k1"].ToInt());  // 7
Print(data["b"]["k2"].ToStr());  // "baz"
Print(data.Serialize());  // {"a":12,"b":{"k1":7,"k2":"baz"}}

If anyone can help, then many MQL-developers will be grateful as this bug has been around for many years.

 

Hi everyone!!!

The JAson documentation is not complete on this site, so I wrote a more detailed documentation https://github.com/vivazzi/JAson/ and added unit tests: maybe someone will find it useful.

And I described the problem of using a nested Json (CJAVal object): https://github.com/vivazzi/JAson/issues/1.

CJAVal object is not correctly saved if you use "=" sign (empty key is saved):

CJAVal data;

// simple structure
data["a"] = 12;

// nested structure
CJAVal nested_data;
nested_data["k1"] = 7;
nested_data["k2"] = "baz";

data["b"] = nested_data;

Print(data["b"]["k1"].ToInt());  // 0 instead of 7
Print(data["b"]["k2"].ToStr());  // "" instead of "baz"
Print(data.Serialize());  // {"a":12,"":{"k1":7, "k2": "baz"}, "b":{}} instead of {"a":12, "b":{"k1":7, "k2": "baz"}}

Yes, in the tests attached on the library page on this site, you can find that you need to use the Set() method:

data["b"].Set(nested_data);

Print(data["b"]["k1"].ToInt());  // 7
Print(data["b"]["k2"].ToStr());  // "baz"
Print(data.Serialize());  // {"a":12,"b":{"k1":7,"k2":"baz"}}

But if someone can fix the library so that it is possible to save nested Json structures via the "=" sign, it would help a lot of people. Since I've noticed that some people think the library has errors when they try to assign a nested CJAVal in the usual way via "=".

I hope this is even possible within the MQL language. I've tried to correct it myself, but I don't have a deep knowledge of the MQL language, and so far it hasn't worked to do assignment via "=".

vivazzi/JAson
vivazzi/JAson
  • vivazzi
  • github.com
Realization of JSON protocol in mql4 / mql5. You can create JSON object with data of different types and run serialization and deserialization of JSON data. Installing Usage Add and create object to work with JSON data. See simple example for easy understand: WARNING : To assign other object to current, use method instead of using the "=" sign...
 
Артём Мальцев:

Hi there!

Documentation of JAson library is not full at this site. I wrote documentation with more details and added unit tests: https://github.com/vivazzi/JAson. It may be useful for someone.

Add i created issue that has description of bug of using inner Json (CJAVal object): https://github.com/vivazzi/JAson/issues/1.

CJAVal object is not correctly assigned to another CJAVal object as object:

As workaround, you need use Set() method:

If anyone can help, then many MQL-developers will be grateful as this bug has been around for many years.

The problem is with the Copy method. 

        virtual bool Copy(const CJAVal &a) {
            m_key=a.m_key;
            CopyData(a);
            return true;
    }

The key gets overwritten with the subobject's key in your example the "b" gets overwritten with the "nested_data"'s key which is empty. 

I used this simple solution, not fully tested: 

virtual bool Copy(const CJAVal &a) { if(m_key=="") m_key=a.m_key; CopyData(a); return true; }
 

Thank you, Laszlo Tormasi - your fix works and all tests have passed!

I updated JAson with your fixes: https://github.com/vivazzi/JAson

 

The problem of assigning nested Json structures via the "=" sign was solved by Laszlo Tormasi in the comment https://www.mql5.com/en/forum/65320/page3#comment_21453129.

JAson version with editsat https://github.com/vivazzi/JAson.


Thanks to everyone who tried to understand the problem and help!

Libraries: JSON Serialization and Deserialization (native MQL)
Libraries: JSON Serialization and Deserialization (native MQL)
  • 2021.03.23
  • www.mql5.com
JSON Serialization and Deserialization (native MQL): Author: o_O...
 
How to manipulate generic serialisation and deserialisation?
 

Fixed an error ("array out of range") that occurred with negative array indices. Now the [] operator returns NULL.

Processing looks like this.

void OnStart()
{
  CJAVal json, * jsC;

  // adding 
  json[0] = 0;
  json[1] = 1;
  json[2] = 2;
  
  // check
  if ((jsC = json[-1]) == NULL)
    Print("Error. jsC is null!");
}

Also, I added the ToIntI method for convenience. Since ToInt returns long.

int ToIntI() const { return (int)m_iv; }
Files:
JAson.mqh  31 kb
JasonTest.mq5  2 kb
 

I don't understand how to read the nested json.

Here is a string like this:

string str=

{
  "key1": [
    {
      "key2": [
        {
          "key3": "val)"
        },
        {},
        {}
      ]
    }
  ]
}

How do I read it and access the elements?

CJAVal data;
data.Deserialize(str);
Print(data["key1"][0][0]["key3"].ToStr());
No matter how I try, it doesn't work.
 
leonerd #:

I don't understand how to read the nested json.

Here is a string like this:

How do I read it and access the elements?

No matter how many times I try, I can't get it.
string str;
CJAVal data;

str=
"{"
"  \"key1\": ["
"    {"
"      \"key2\": ["
"        {"
"          \"key3\": \"val)\""
"        },"
"        {},"
"        {}"
"      ]"
"    }"
"  ]"
"}";

data.Deserialize(str);
Print(data["key1"][0]["key2"][0]["key3"].ToStr());

If you don't understand the structure of your json string or something goes wrong, do the following:

string str;
CJAVal data; 
CJAVal *value;

str=
"{"
"  \"key1\": ["
"    {"
"      \"key2\": ["
"        {"
"          \"key3\": \"val)\""
"        },"
"        {},"
"        {}"
"      ]"
"    }"
"  ]"
"}";

data.Deserialize(str);

if ((value = data["key1"]) == NULL) {
  Print("Value is NULL! Line: ", __LINE__);
  return;
}

if ((value = value[0]) == NULL) {
  Print("Value is NULL! Line: ", __LINE__);
  return;
}

if ((value = value["key2"]) == NULL) {
  Print("Value is NULL! Line: ", __LINE__);
  return;
}

if ((value = value[0]) == NULL) {
  Print("value is NULL! Line: ", __LINE__);
  return;
}

if ((value = value["key3"]) == NULL) {
  Print("Value is NULL! Line: ", __LINE__);
  return;
}

Print(value.ToStr());

To easily understand the structure of a json string use this site: https: //jsoneditoronline.org/.

JSON Editor Online - view, edit and format JSON online
  • Jos de Jong
  • jsoneditoronline.org
JSON Editor Online is a web-based tool to view, edit, format, transform, and diff JSON documents.