程序库: 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]

也就是说,最后两个有效字符丢失了,数组中的所有值都变得彼此相等。因此,根据这些数据进行的所有计算都是徒劳的....。

最后,我通过将数组值转换为字符串来解决这个问题。

Документация по 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,"":{"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 开发人员将会非常感激,因为这个 bug 已存在多年。

 

大家好

这个网站上的 JAson 文档并不完整,所以我写了一个更详细的文档https://github.com/vivazzi/JAson/ 并添加了单元测试:也许有人会觉得有用。

我还描述了使用嵌套 Json(CJAVal 对象)的问题:https://github.com/vivazzi/JAson/issues/1。

如果使用"="符号,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,"":{"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"}}

但是,如果有人能修复程序库,使其可以通过"="号保存嵌套的 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 开发人员都会非常感激,因为这个 bug 已经存在很多年了。

问题出在复制方法上。

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

在你的例子中,键被子对象的键覆盖,"b "被 "nested_data "的键覆盖,而 "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

 

Laszlo Tormasi 在 https://www.mql5.com/en/forum/65320/page3#comment_21453129 的评论中 解决了通过"="符号 分配嵌套Json 结构 的问题。

带编辑的 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...
 
怎么操作泛型序列化与反序列化?
 

修正了负数组索引 时出现的错误("数组超出范围")。现在 [] 操作符返回 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
 

我不知道如何读取嵌套的 json。

下面是这样一个字符串

string str=

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

如何读取并访问其中的元素?

CJAVal data;
data.Deserialize(str);
Print(data["key1"][0][0]["key3"].ToStr());
无论我怎么尝试,都行不通。
 
leonerd #:

我不知道如何读取嵌套的 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.