Библиотеки: JSON Serialization and Deserialization (native MQL) - страница 14

 

Библиотека очень полезная. Но столкнулся с тем, что при сериализации значений типа double происходит сильная потеря точности

Пример:

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]);

После сериализации получаю:

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

Т.е. последние 2 значащих знака просто потеряны и все значения в массиве стали попросту равны друг другу. В результате все расчеты на основе этих данных идут прахом...

В итоге обошел это преобразованием значений массива в string.

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

Привет!

Документация по библиотеке JAson на этом сайте не полная. Я написал документацию более подробно и добавил юнит-тесты: https://github.com/vivazzi/JAson. Возможно, кому-то это будет полезно.

Добавлю, что я создал проблему, в которой описана ошибка использования внутреннего Json (объект CJAVal): https://github.com/vivazzi/JAson/issues/1.

Объект CJAVal некорректно присваивается другому объекту CJAVal в качестве объекта:

CJAVal data;

// простая структура
data["a"] = 12;

// вложенная структура
CJAVal nested_data;
nested_data["k1"] = 7;
nested_data["k2"] = "baz";

data["b"] = nested_data;

Print(data["b"]["k1"].ToInt());  // 0 вместо 7
Print(data["b"]["k2"].ToStr());  // "" вместо "baz"
Print(data.Serialize());  // {"a":12, "b":{"k1":7, "k2": "baz"}, "b":{}} вместо {"a":12, "b":{"k1":7, "k2": "baz"}}

В качестве обходного пути необходимо использовать метод Set():

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"}}

Если кто-то сможет помочь, то многие MQL-разработчики будут благодарны, так как эта ошибка существует уже много лет.

 

Всем привет!

Документация JAson не полная на этом сайте, и я написал более подробную документацию https://github.com/vivazzi/JAson/, а также добавил юнит-тесты: может быть кому-нибудь будет это полезно.

И я описал проблему использования вложенного Json (CJAVal объекта): https://github.com/vivazzi/JAson/issues/1.

CJAVal объект не корректно сохраняется, если использовать знак "=" (сохраняется пустой ключ):

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"}}

Да, в тестах, прилагаемом на странице библиотеки на этом сайте, можно найти, что нужно использовать метод Set():

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"}}

Но если кто-нибудь сможет поправить библиотеку так, чтобы можно было сохранять вложенные Json структуры через знак "=", то это бы очень помогло многим. Так как я заметил, что некоторые думают, что библиотека имеет ошибки, когда пытаются присвоить вложенный CJAVal обычным способом через "=".

Надеюсь, это вообще возможно в рамках MQL языка. Я сам пробовал поправить, но у меня нет глубоких знаний языка MQL, и пока не получилось сделать присваивание через "=".

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...
 
Артём Мальцев:

Привет!

Документация по библиотеке JAson на этом сайте не полная. Я написал документацию более подробно и добавил юнит-тесты: https://github.com/vivazzi/JAson. Возможно, кому-то это будет полезно.

Добавлю, что я создал вопрос, в котором описана ошибка использования внутреннего Json (объект CJAVal): https://github.com/vivazzi/JAson/issues/1.

Объект CJAVal некорректно присваивается другому объекту CJAVal в качестве объекта:

В качестве обходного пути необходимо использовать метод Set():

Если кто-то сможет помочь, то многие MQL-разработчики будут благодарны, так как эта ошибка существует уже много лет.

Проблема заключается в методе Copy.

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

Ключ перезаписывается ключом подобъекта, в вашем примере ключ "b" перезаписывается ключом "nested_data", который пуст.

Я использовал это простое решение, не до конца протестированное:

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

Спасибо, Laszlo Tormasi - ваше исправление работает, и все тесты пройдены!

Я обновил JAson с вашими исправлениями: https://github.com/vivazzi/JAson

 

Проблема присваивания вложенных Json структур через знак "=" была решена Laszlo Tormasi в комментарии https://www.mql5.com/en/forum/65320/page3#comment_21453129.

Версия JAson с правками на https://github.com/vivazzi/JAson


Спасибо всем, кто пытался разобраться в проблеме и помочь!

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...
 
Как управлять общей сериализацией и десериализацией?
 

Исправил ошибку ("array out of range"), которая возникала при отрицательных индексах массива. Теперь оператор [] возвращает NULL.

Обработка выглядит так.

void OnStart()
{
  CJAVal json, * jsC;

  // добавление 
  json[0] = 0;
  json[1] = 1;
  json[2] = 2;
  
  // проверка
  if ((jsC = json[-1]) == NULL)
    Print("Error. jsC is null!");
}

Также, добавил метод ToIntI, для удобства. Поскольку, ToInt возвращает long.

int ToIntI() const { return (int)m_iv; }
Файлы:
JAson.mqh  31 kb
JasonTest.mq5  2 kb
 

Не пойму, как nested json прочитать.

Вот есть строка вида: 

string str=

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

И как её прочитать и получить доступ к элементам?

CJAVal data;
data.Deserialize(str);
Print(data["key1"][0][0]["key3"].ToStr());
Как только не пытался - не получается.
 
leonerd #:

Не пойму, как nested json прочитать.

Вот есть строка вида: 

И как её прочитать и получить доступ к элементам?

Как только не пытался - не получается.
string str;
CJAVal data;

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

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

Если плохо понимаете структуру вашей json строки или что-то идёт не так, то делайте следующим образом:

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());

Чтобы легко понять структуру json строки пользуйтесь этим сайтом: 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.