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

 
Как можно пробежаться по всем элементам JsonArray? 

Например {"ABC":{...}, "DEF":{...}, "GHI":{...}}, заранее не знаю названия элементов, как пробежаться по всем?
 

Библиотека очень полезная. Но столкнулся с тем, что при сериализации значений типа 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 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...
 

Проблема присваивания вложенных 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.
 

Artem Maltsev, рекомендую вам добавить мою версию, поскольку, у скачавших модуль сделать так не получится:   .

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

Подскажите, как добавить округление в double


Есть вариант ниже, но он добавляет квадратные скобки. 

      CJAVal js(NULL,jtUNDEF);
      double d = 0.05;
      js["OrderLot"].Add(d,2); //результат "OrderLot":[0.05].   

Как получить?

"OrderLot":0.05
 

Доброго времени суток!

Крутая библиотека очень помогает, огромное спасибо.

Только вот столкнулся с такой проблемой - как вытащить подстроку из строки:

Есть строка 

{"type":"settings","data":{"auto_trade":true,"stop_trade":true}}

нужно вытащить подстроку data.

Так не получается:

CJAVal js;

js.Deserialize(stroka);

js["data"].ToStr();

Причина обращения: