Bibliotecas: Serialização e desserialização de JSON (MQL nativo) - página 14

 

A biblioteca é muito útil. Mas percebi que, ao serializar valores do tipo double, há uma grande perda de precisão.

Exemplo:

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

Após a serialização, obtenho:

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

Ou seja, os dois últimos caracteres significativos são simplesmente perdidos e todos os valores da matriz se tornam simplesmente iguais uns aos outros. Como resultado, todos os cálculos baseados nesses dados são em vão....

No final, consegui contornar o problema convertendo os valores da matriz em string.

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

Olá!

A documentação da biblioteca JAson não está completa neste site. Escrevi a documentação com mais detalhes e adicionei testes unitários: https://github.com/vivazzi/JAson. Ela pode ser útil para alguém.

Além disso, criei um problema que contém a descrição do erro de uso do Json interno (objeto CJAVal): https://github.com/vivazzi/JAson/issues/1.

O objeto CJAVal não é atribuído corretamente a outro objeto CJAVal como objeto:

CJAVal data;

// estrutura simples
data["a"] = 12;

// estrutura aninhada
CJAVal nested_data;
nested_data["k1"] = 7;
nested_data["k2"] = "baz";

data["b"] = nested_data;

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

Como solução alternativa, é necessário usar o método 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"}}

Se alguém puder ajudar, muitos desenvolvedores de MQL ficarão gratos, pois esse erro já existe há muitos anos.

 

Olá a todos!!!

A documentação do JAson não está completa neste site, então escrevi uma documentação mais detalhada https://github.com/vivazzi/JAson/ e adicionei testes de unidade: talvez alguém ache útil.

E descrevi o problema de usar um Json aninhado (objeto CJAVal): https://github.com/vivazzi/JAson/issues/1.

O objeto CJAVal não é salvo corretamente se você usar o sinal "=" (a chave vazia é salva):

CJAVal data;

// estrutura simples
data["a"] = 12;

// estrutura aninhada
CJAVal nested_data;
nested_data["k1"] = 7;
nested_data["k2"] = "baz";

data["b"] = nested_data;

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

Sim, nos testes anexados na página da biblioteca neste site, você pode descobrir que precisa usar o método 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"}}

Mas se alguém puder corrigir a biblioteca para que seja possível salvar estruturas Json aninhadas por meio do sinal "=", isso ajudaria muitas pessoas. Como notei que algumas pessoas acham que a biblioteca tem erros quando tentam atribuir um CJAVal aninhado da maneira usual por meio de "=".

Espero que isso seja possível até mesmo na linguagem MQL. Eu mesmo tentei corrigir isso, mas não tenho um conhecimento profundo da linguagem MQL e, até agora, não funcionou a atribuição por meio de "=".

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

Olá!

A documentação da biblioteca JAson não está completa neste site. Escrevi a documentação com mais detalhes e adicionei testes unitários: https://github.com/vivazzi/JAson. Ela pode ser útil para alguém.

Além disso, criei um problema com a descrição do erro de uso do Json interno (objeto CJAVal): https://github.com/vivazzi/JAson/issues/1.

O objeto CJAVal não é atribuído corretamente a outro objeto CJAVal como objeto:

Como solução alternativa, você precisa usar o método Set():

Se alguém puder ajudar, muitos desenvolvedores de MQL ficarão gratos, pois esse bug já existe há muitos anos.

O problema é com o método Copy.

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

A chave é substituída pela chave do subobjeto; em seu exemplo, o "b" é substituído pela chave do "nested_data", que está vazio.

Usei esta solução simples, não totalmente testada:

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

Obrigado, Laszlo Tormasi - sua correção funciona e todos os testes foram aprovados!

Atualizei o JAson com suas correções: https://github.com/vivazzi/JAson

 

O problema de atribuir estruturas Json aninhadas por meio do sinal "=" foi resolvido por Laszlo Tormasi no comentário https://www.mql5.com/en/forum/65320/page3#comment_21453129.

Versão JAson com ediçõesem https://github.com/vivazzi/JAson.


Obrigado a todos que tentaram entender o problema e ajudar!

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...
 
Como manipular a serialização e a desserialização genéricas?
 

Foi corrigido um erro ("matriz fora do intervalo") que ocorria com índices de matriz negativos. Agora o operador [] retorna NULL.

O processamento tem a seguinte aparência.

void OnStart()
{
  CJAVal json, * jsC;

  // adição 
  json[0] = 0;
  json[1] = 1;
  json[2] = 2;
  
  // verificar
  if ((jsC = json[-1]) == NULL)
    Print("Error. jsC is null!");
}

Além disso, adicionei o método ToIntI por conveniência. Como ToInt retorna long.

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

Não entendo como ler o json aninhado.

Aqui está uma string como esta:

string str=

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

Como faço para lê-la e acessar os elementos?

CJAVal data;
data.Deserialize(str);
Print(data["key1"][0][0]["key3"].ToStr());
Não importa o quanto eu tente, não funciona.
 
leonerd #:

Não entendo como ler o json aninhado.

Aqui está uma string como esta:

Como faço para lê-la e acessar os elementos?

Não importa quantas vezes eu tente, não consigo.
string str;
CJAVal data;

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

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

Se você não entender a estrutura de sua cadeia de caracteres json ou se algo der errado, faça o seguinte:

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

Para entender facilmente a estrutura de uma cadeia de caracteres json, use este 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.