玩转ArduinoJson库 V6版本

1.前言

????前面,博主已经讲解了ArduinoJson库的V5版本。为了节省时间以及不讨论重复内容,博主建议读者先去阅读一下 玩转ArduinoJson库 V5版本 。重点了解几个东西:

  • JSON协议
  • JsonBuffer
  • JsonObject
  • JsonArray

????接下来,我们直接进入V6版本的学习,尽量和V5版本类比。

2.ArduinoJson V6版本

????假设读者下载的V6版本的,那么可以参考 这里 的API说明。读者需要注意一下JsonDocument(可类比V5版本的JsonBuffer),因为V6版本的json操作都是在它上面。
????对于开发者来说,使用JSON无非就是编码或者解码,所以博主也会分出两种情况来讲解。
????首先我们来看看V6版本常用的百度脑图:

????可以看出,方法主要分为三大类:

  • JsonDocument相关,这是整个json库的入口,它负责高效管理内存以及调用json解析器;
  • JsonObject相关;
  • JsonArray相关;
  • 解析、构造相关;

2.0 解析、构造相关

2.0.1 deserializeJson —— 解析json

函数说明
详细可以参考 wiki

/**
 * 解析json
 * @param doc jsondocument对象
 * @param input 输入内容
 * @return DeserializationError 解析结果
 */
// writable input => zero-copy
DeserializationError deserializeJson(JsonDocument& doc, char* input);
DeserializationError deserializeJson(JsonDocument& doc, char* input, size_t inputSize);

// read-only input => duplication
DeserializationError deserializeJson(JsonDocument& doc, const char* input);
DeserializationError deserializeJson(JsonDocument& doc, const char* input, size_t inputSize);
DeserializationError deserializeJson(JsonDocument& doc, const __FlashStringHelper* input);
DeserializationError deserializeJson(JsonDocument& doc, const __FlashStringHelper* input, size_t inputSize);
DeserializationError deserializeJson(JsonDocument& doc, const String& input);
DeserializationError deserializeJson(JsonDocument& doc, const std::string& input);
DeserializationError deserializeJson(JsonDocument& doc, Stream& input);
DeserializationError deserializeJson(JsonDocument& doc, std::istream& input);

DeserializationError具体内容请参考 wiki

例子说明

//Read-only input
const char* json = "{\"hello\":\"world\"}";
StaticJsonDocument<200> doc;
deserializeJson(doc, json);
const char* world = doc["hello"];

//Zero-copy mode
char json[] = "{\"hello\":\"world\"}";
StaticJsonDocument<200> doc;
deserializeJson(doc, json);
const char* world = doc["hello"];

//Raise the nesting limit
char json[] = "[[[[[[[[[[[[[[[42]]]]]]]]]]]]]]]";
StaticJsonDocument<200> doc;
deserializeJson(doc, json, DeserializationOption::NestingLimit(15));;
int answer = doc[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0];

2.0.2 serializeJson —— 构造序列化json

函数说明
详细可以参考 wiki

/**
 * 构造序列化json
 * @param doc jsondocument对象
 * @param output 输出内容
 */
serializeJson(const JsonDocument& doc, char* output, size_t outputSize);
serializeJson(const JsonDocument& doc, char output[size]);
serializeJson(const JsonDocument& doc, Print& output);
serializeJson(const JsonDocument& doc, String& output);
serializeJson(const JsonDocument& doc, std::string& output);
serializeJson(const JsonDocument& doc, std::ostream& output);

例子说明

StaticJsonDocument<200> doc;
doc["hello"] = "world";
serializeJson(doc, Serial);

打印结果:

{"hello":"world"}

注意

  • 此方法属于精简压缩化输出;

2.0.3 serializeJsonPretty —— 构造序列化json,格式化输出

函数说明
详细可以参考 wiki

/**
 * 构造序列化json,格式化输出
 * @param doc jsondocument对象
 * @param output 输出内容
 */
size_t serializeJsonPretty(const JsonDocument& doc, char* output, size_t outputSize);
size_t serializeJsonPretty(const JsonDocument& doc, char output[size]);
size_t serializeJsonPretty(const JsonDocument& doc, Print& output);
size_t serializeJsonPretty(const JsonDocument& doc, String& output);
size_t serializeJsonPretty(const JsonDocument& doc, std::string& output);

例子说明

StaticJsonDocument<200> doc;
doc["hello"] = "world";
serializeJsonPretty(doc, Serial);

打印结果:

{
  "hello": "world"
}

注意

  • 此方法属于格式化输出,需要考虑内存消耗;

2.0.4 measureJson —— 计算构造序列化json的长度

函数说明
详细可以参考 wiki

/**
 * 计算构造序列化json的长度
 * @param doc jsondocument对象
 * @Note 关联方法 serializeJson
 */
size_t measureJson(const JsonDocument& doc);

例子说明

// Send headers
client.println("Content-Type: application/json");
client.print("Content-Length: ");
client.println(measureJson(doc));

// Terminate headers
client.println();

// Send body
serializeJson(doc, client);

2.0.5 measureJsonPretty —— 计算构造序列化格式化json的长度

函数说明
详细可以参考 wiki

/**
 * 计算构造序列化格式化json的长度
 * @param doc jsondocument对象
 * @Note 关联方法  serializeJsonPretty
 */
size_t measureJsonPretty(const JsonDocument& doc);

例子说明

// Send headers
client.println("Content-Type: application/json");
client.print("Content-Length: ");
client.println(measureJsonPretty(doc));

// Terminate headers
client.println();

// Send body
serializeJsonPretty(doc, client);

2.1 JsonDocument

????JsonDocument作为整个V6版本ArduinoJson库的内存入口,负责处理整个json数据的内存管理,这是我们需要首先重点关注的内容。
????它包括两个实现类:

  • DynamicJsonDocument,内存分配在heap区,无固定大小,可以自动增长所需空间,方法调用完自动回收,建议内存大小大于1KB使用;
StaticJsonDocument<256> doc;
  • StaticJsonDocument,内存分配在stack区,有固定大小,大小值由开发者定义,方法调用完自动回收,建议内存大小小于1KB使用;
DynamicJsonDocument doc(2048);

使用JsonDocument
????当你创建一个JsonDocument之后,默认初始化为空,调用 JsonDocument::isNull()会返回true,这个时候既可以代表当做jsonObject,也可以当做jsonArray,这取决于你插入第一个value的类型。

????以下会作为JsonObject使用:

DynamicJsonDocument doc(1024);
doc["answer"] = 42;
// the doc contains {"answer":42}

????以下会作为JsonArray使用:

DynamicJsonDocument doc(1024);
doc.add(42);
// the doc contains [42]

????接下来,看看JsonDocument的一些常用方法:

2.1.1 as —— 获取顶节点,并把它转成T类型

函数说明

/**
 * 获取顶节点,并把它转成T类型
 * @return JsonArray/JsonObject/JsonVariant
 */
JsonArray   as<JsonArray>();
JsonObject  as<JsonObject>();
JsonVariant as<JsonVariant>();

例子说明

DynamicJsonBuffer doc(1024);
deserializeJson(doc, "{\"key\":\"value\")");

// get the JsonObject in the JsonDocument
JsonObject root = doc.as<JsonObject>();

// get the value in the JsonObject
const char* value = root["key"];

注意:

  • 此方法不会改变 JsonDocument的内容(JsonDocument::to()会改变)
  • 此方法只会返回JsonDocument顶节点的引用。如果顶节点的类型和强转的T类型不匹配,此方法将会返回空引用(比如,如果JsonDocument是一个jsonArray,当调用JsonDocument::as(),会返回空JsonObject)。

2.1.2 add —— 往jsondocument添加元素

函数说明

/**
 * 往jsondocument添加元素
 * @param value 元素
 */
// add the specified value to the array
bool add(bool value);

bool add(float value);
bool add(double value);

bool add(signed char value);
bool add(signed long value);
bool add(signed int value);
bool add(signed short value);
bool add(unsigned char value);
bool add(unsigned long value);
bool add(unsigned int value);
bool add(unsigned short value);

bool add(char *value); // see Remarks
bool add(const char *value);
bool add(const __FlashStringHelper *value); // see Remarks

bool add(const String &value); // see Remarks
bool add(const std::string &value); // see Remarks

bool add(JsonArray array);
bool add(JsonObject object);
bool add(JsonVariant variant);

例子说明

StaticJsonDocument<200> doc;
array.add("hello"); // null -> ["hello"]
array.add(3.14156); // ["hello"] -> ["hello",3.14156]
serializeJson(doc, Serial);

打印结果:

["hello",3.14156]

注意:

  • 如果JsonDocument顶节点是一个JsonArray,add方法会追加一个value到数组;
  • 如果JsonDocument顶节点是一个JsonObject,add无效;
  • 如果JsonDocument是一个空对象,add方法会把JsonDocument变成一个包含一个元素的数组,这是一个创建数组的方式;

2.1.3 clear —— 清除JsonDocument并释放内存空间

函数说明

/**
 * 清除JsonDocument并释放内存空间
 */
void clear();

注意:

  • 这个方法和JsonBuffer的clear方法不一样;

2.1.4 createNestedArray —— 创建空json数组,并为它分配内存空间

函数说明

/**
 * 创建空json数组,并为它分配内存空间
 * @param key key名称
 * @return JsonArray
 */
// similar to JsonArray::createNestedArray()
JsonArray createNestedArray();

// similar to JsonObject::createNestedArray()
JsonArray createNestedArray(char* key);
JsonArray createNestedArray(const char* key);
JsonArray createNestedArray(const __FlashStringHelper* key);
JsonArray createNestedArray(const String& key);
JsonArray createNestedArray(const std::string& key);

例子说明

DynamicJsonDocument doc(1024);
JsonArray ports = doc.createNestedArray("ports");
ports.add("80");
ports.add("443");

打印结果:

{
    "ports": [
        80,
        443
    ]
}

注意:

  • 对于无参数的createNestedArray()方法,会创建一个Json数组并把它追加到顶节点的数组中。如果document的顶节点不是数组,这个方法无效;如果document是空的,这个方法会初始化一个数组顶节点,参考以下代码:
StaticJsonDocument<200> doc;

JsonArray arr = doc.createNestedArray();
arr.add("hello world");

serializeJson(doc, Serial);

打印结果:

[["hello world"]]
  • 对于有参数的createNestedArray()方法,会创建一个json数组并把它指向这个特定的key。如果document的顶节点不是对象,这个方法无效;如果document是空的,这个方法会初始化一个对象顶节点,参考以下代码:
StaticJsonDocument<200> doc;

JsonArray array = doc.createNestedArray("hello");
array.add("world");

serializeJson(doc, Serial);

打印结果:

{"hello":["world"]}

2.1.5 createNestedObject —— 创建空json对象,并为它分配内存空间

函数说明

/**
 * 创建空json对象,并为它分配内存空间
 * @param key key名称
 * @return JsonObject
 */
// similar to JsonArray::createNestedArray()
// similar to JsonArray::createNestedObject()
JsonObject createNestedObject();

// similar to JsonObject::createNestedObject()
JsonObject createNestedObject(char* key);
JsonObject createNestedObject(const char* key);
JsonObject createNestedObject(const __FlashStringHelper* key);
JsonObject createNestedObject(const String& key);
JsonObject createNestedObject(const std::string& key);

例子说明

DynamicJsonDocument doc(1024);
JsonArray wifi  = doc.createNestedObject("wifi");
wifi["SSID"] = "TheBatCave";

打印结果:

{
    "wifi": {
        "SSID": "TheBatCave"
    }
}

注意:

  • 对于无参数的createNestedObject()方法,会创建一个Json对象并把它追加到顶节点的数组中。如果document的顶节点不是数组,这个方法无效;如果document是空的,这个方法会初始化一个数组顶节点,参考以下代码:
StaticJsonDocument<200> doc;

JsonObject obj = doc.createNestedObject();
obj["hello"] = "world";

serializeJson(doc, Serial);

打印结果:

[{"hello":"world"}]
  • 对于有参数的createNestedObject()方法,会创建一个json数组并把它指向这个特定的key。如果document的顶节点不是对象,这个方法无效;如果document是空的,这个方法会初始化一个对象顶节点,参考以下代码:
StaticJsonDocument<200> doc;

JsonObject obj = doc.createNestedObject("nested");
obj["hello"] = "world";

serializeJson(doc, Serial);

打印结果:

{"nested":{"hello":"world"}}

2.1.6 getElement —— 获取index位置/key的元素

函数说明

/**
 * 获取index位置/key的元素
 * @param index 索引位置
 * @return JsonVariant 如果找不到匹配的返回null
 */
JsonVariant getElement(size_t index);

2.1.7 getMember —— 获取key对应的value

函数说明

/**
 * 获取key对应的value
 * @param key 对应的key
 * @param JsonVariant key对应的value,如果不匹配返回null
 */
JsonVariant getMember(const char* key);
JsonVariant getMember(String key);
JsonVariant getMember(std::string key);
JsonVariant getMember(const __FlashStringHelper* key);

2.1.8 getOrCreateMember —— 获取或者创建key对应的value

函数说明

/**
 * 获取或者创建key对应的value
 * @param key 对应的key
 * @param JsonVariant key对应的value,如果不匹配返回null
 */
JsonVariant getOrCreateMember(const char* key);
JsonVariant getOrCreateMember(String key);
JsonVariant getOrCreateMember(std::string key);
JsonVariant getOrCreateMember(const __FlashStringHelper* key);

注意

  • 如果JsonDocument包含一个对象,那么getOrCreateMember方法会获取指定key的值,如果对象不存在该key,这个方法会往对象添加一个新的key-value键值对;
  • 如果JsonDocument是空,那么getOrCreateMember方法将创建一个对象给到JsonDocument;
  • 如果属于以上两种情况之外的,此方法无效;

2.1.9 operator[] —— 快捷操作符

函数说明

/**
 * 快捷操作符
 * @param key 对象中对应的key
 * @param index 数组中对应的索引
 */
// mimics a JsonArray
ElementProxy operator[](size_t index);

// mimics a JsonObject
MemberProxy operator[](const char* key);
MemberProxy operator[](char* key);
MemberProxy operator[](const String& key);
MemberProxy operator[](const std::string& key);
MemberProxy operator[](const __FlashStringHelper* key);

例子说明

StaticJsonDocument<256> doc;
doc["wifi"]["SSID"] = "TheBatCave";

打印内容:

{
    "wifi": {
        "SSID": "TheBatCave"
    }
}

2.1.10 isNull —— 判断jsondocument是否为空

函数说明

/**
 * 判断jsondocument是否为空
 */
bool isNull() const;

例子说明

//Result is true
DynamicJsonDocument doc(1024);
doc.isNull(); // true
serializeJson(doc, Serial); // prints "null"

//Result is false
DynamicJsonDocument doc(1024);
doc.to<JsonArray>();
doc.isNull(); // false
serializeJson(doc, Serial); // prints "[]"

2.1.11 memoryUsage —— jsondocument已使用内存字节数

函数说明

/**
 * jsondocument已使用内存字节数
 */
size_t memoryUsage() const;

例子说明

char json[] = "{\"hello\":\"world\"}";
StaticJsonDocument<200> doc;
deserializeJson(doc, json);

Serial.println(doc.memoryUage());
// prints 26 on AVR

2.1.12 to —— jsondocument转成T类型

函数说明

/**
 * jsondocument转成T类型,T为JsonArray、JsonObject、JsonVariant
 */
JsonArray   to<JsonArray>();
JsonObject  to<JsonObject>();
JsonVariant to<JsonVariant>();

例子说明

// allocate the JsonDocument
StaticJsonDocument<200> doc;

// convert it to a JsonObject
JsonObject root = doc.to<JsonObject>();

// set values
root["hello"] = "world";

注意

  • 此方法是释放jsondocument的内存空间,也就是说之前已经分配的引用无效,参考代码:
DynamicJsonBuffer doc(1024);

JsonObject root1 = doc.to<JsonObject>();

JsonObject root2 = doc.to<JsonObject>();

// Don't use root1 here, because it's dangling!

2.2 JsonObject

????在JsonDocument所构造出来的内存空间中,Json对象的入口就是JsonObject。
????让我们看看它的常用操作方法:

2.2.1 begin/end —— 返回一个迭代器,可用于对象中的所有键值对

函数说明

/**
 * 返回一个迭代器,可用于对象中的所有键值对
 */
JsonObject::iterator begin() const;
JsonObject::iterator end() const;

例子说明

char json[] = "{\"first\":\"hello\",\"second\":\"world\"}";
DynamicJsonDocument doc(1024);
deserializeJson(doc, json);
JsonObject root = doc.as<JsonObject>();

// using C++11 syntax (preferred):
for (JsonPair kv : root) {
    Serial.println(kv.key().c_str());
    Serial.println(kv.value().as<char*>());
}

// using C++98 syntax (for older compilers):
for (JsonObject::iterator it=root.begin(); it!=root.end(); ++it) {
    Serial.println(it->key().c_str());
    Serial.println(it->value().as<char*>());
}

打印结果:

first
hello
second
world

2.2.2 containsKey —— 判断对象是否包含某一个key

函数说明

/**
 * 判断对象是否包含某一个key
 * @param key key名字
 * @return bool
 */
bool containsKey(const char* key) const;
bool containsKey(const String& key) const;
bool containsKey(const std::string& key) const;
bool containsKey(const __FlashStringHelper& key) const;

例子说明

StaticJsonDocument<256> doc;
JsonObject root = doc.to<JsonObject>();
root["city"] = "Paris";

bool hasCity = root.containsKey("city"); // true
bool hasCountry = root.containsKey("country"); // false
}

注意

  • json库的开发者不建议使用该方法,因为就算没有值也会返回一个空值。库开发者给了例子建议:
if (root.containsKey("error")) {
  const char* error = root["error"]
  Serial.println(error);
  return;
}

可以改成:

JsonVariant error = root["error"];
if (!error.isNull()) {
  Serial.println(error.as<char*>());
  return;
}

或者更加简单快速的方法:

const char* error = root["error"];
if (error) {
  Serial.println(error);
  return;
}

2.2.3 createNestedArray —— 在当前对象中添加子key,子value为json数组

函数说明

/**
 * 在当前对象中添加子key,子value为json数组
 * @param key key名字
 * @return JsonArray
 */
JsonArray createNestedArray(char* key) const;
JsonArray createNestedArray(const char* key) const;
JsonArray createNestedArray(const __FlashStringHelper* key) const;

JsonArray createNestedArray(const String& key) const;
JsonArray createNestedArray(const std::string& key) const;

例子说明

StaticJsonDocument<256> doc;
JsonObject root = doc.to<JsonObject>();
root["status"] = "on";
JsonArray levels = root.createNestedArray("levels");
levels.add(10);
levels.add(30);
serializeJsonPretty(root, Serial);

打印结果:

{
  "status": "on",
  "levels": [
    10,
    20
  ]
}

2.2.4 createNestedObject —— 在当前对象中添加子key,子value为json对象

函数说明

/**
 * 在当前对象中添加子key,子value为json对象
 * @param key key名字
 * @return JsonObject对象
 */
JsonObject createNestedObject(char* key) const;
JsonObject createNestedObject(const char* key) const;
JsonObject createNestedObject(const __FlashStringHelper* key) const;

JsonObject createNestedObject(const String& key) const; // see Remarks
JsonObject createNestedObject(const std::string& key) const; // see Remarks

例子说明

StaticJsonDocument<256> doc;
JsonObject root = doc.to<JsonObject>();
root["city"] = "Paris";
JsonObject weather = root.createNestedObject("weather");
weather["temp"] = 14.2;
weather["cond"] = "cloudy";
serializeJsonPretty(root, Serial);

打印结果:

{
  "city": "Paris",
  "weather": {
    "temp": 14.20,
    "cond": "cloudy"
  }
}

2.2.5 getMember —— 获取对象中给到key的value

函数说明

/**
 * 获取对象中给到key的value
 * @param key key名字
 * @return JsonVariant对象
 */
JsonVariant getMember(const char* key) const;
JsonVariant getMember(const __FlashStringHelper* key) const;

JsonVariant getMember(const String& key) const;
JsonVariant getMember(const std::string& key) const;

例子说明
例子1:

//The key is not found
char json[] = "{\"username\":\"the_duke\"}";

StaticJsonDocument<256> doc;
deserializeJson(doc, json);

JsonObject object = doc.as<JsonObject>();

JsonVariant password = object.getMember("password");
if (password.isNull()) {
  Serial.println(F("Error: password is missing"));
}

打印结果:

Error: password is missing

例子2:

//The key is found
char json[] = "{\"username\":\"the_duke\"}";

StaticJsonDocument<256> doc;
deserializeJson(doc, json);

JsonObject object = doc.as<JsonObject>();

JsonVariant username = object.getMember("username");
Serial.println(F("Your name is: "));
Serial.println(username.as<const char*>());

打印结果:

Your name is: the_duke

2.2.6 getOrCreateMember —— 获取对象中给到key的value,如果没有就创建

函数说明

/**
 * 获取对象中给到key的value,如果没有就创建
 * @param key key名字
 * @return JsonVariant对象
 */
JsonVariant getOrCreateMember(char* key) const;
JsonVariant getOrCreateMember(const char* key) const;
JsonVariant getOrCreateMember(const __FlashStringHelper* key) const;

JsonVariant getOrCreateMember(const String& key) const;
JsonVariant getOrCreateMember(const std::string& key) const;

2.2.7 isNull —— 判断对象是否为空

函数说明

/**
 * 判断对象是否为空
 * @Note You can use this function to:
 *   check if the object was successfully parsed, or
 *   check if the object was successfully allocated.
 */
bool isNull() const;

例子说明

//Example 1: parsing success:
StaticJsonDocument<200> doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonObject object = doc.as<JsonObject>();
Serial.println(object.isNull()); // false

//Example 2: parsing failure:
StaticJsonDocument<200> doc;
deserializeJson(doc, "[\"hello\",\"world\"]");
JsonObject object = doc.as<JsonObject>();
Serial.println(object.isNull()); // true

//Example 3: allocation success:
StaticJsonDocument<200> doc;
JsonObject object = doc.to<JsonObject>();
Serial.println(object.isNull()); // false

//Example 4: allocation failure:
StaticJsonDocument<1> doc;
JsonObject object = doc.to<JsonObject>();
Serial.println(object.isNull()); // true

2.2.8 operator[] —— get/set快捷方式

函数说明

/**
 * get/set快捷方式
 */
MemberProxy operator[](char* key) const;
MemberProxy operator[](const char* key) const;
MemberProxy operator[](const __FlashStringHelper* key) const;

MemberProxy operator[](const String& key) const;
MemberProxy operator[](const std::string& key) const;

例子说明

//以下两行代码效果等同
JsonVariant value = object["key"];
JsonVariant value = object.getMember("key");

//以下两行代码效果等同
object["key"] = "value";
object.getOrCreateMember("key").set("value");

StaticJsonDocument<256> doc;
JsonObject object = doc.to<JsonObject>();
object["hello"] = "world";
const char* world = object["hello"];

2.2.9 remove —— 移除特定key和value

函数说明

/**
 * 移除特定key和value
 * @param key key名
 */
void remove(const char* key) const;
void remove(const __FlashStringHelper* key) const;

void remove(const String& key) const;
void remove(const std::string& key) const;

例子说明

JsonObject object = doc.to<JsonObject>();
object["A"] = 1;
object["B"] = 2;
object["C"] = 3;
object.remove("B");
serializeJson(object, Serial);

打印结果:

{"A":1,"C":3}

注意

  • 该方法只会移除key-value,但是并不会释放key-value对应的jsondocument空间,也不建议在循环中同时add和remove key-value;

2.2.10 set —— 把一个json对象的内容设置给当前json对象

函数说明

/**
 * 把一个json对象的内容设置给当前json对象
 */
bool set(JsonObjectConst obj) const;

2.2.11 size —— 返回对象键值对的个数

函数说明

/**
 * 返回对象键值对的个数
 * @return size_t 个数
 */
size_t size() const;

例子说明

JsonObject object = doc.to<JsonObject>();
object["hello"] = "world";
Serial.println(object.size()); // 1

2.3 JsonArray

????在JsonDocument所构造出来的内存空间中,Json数组的入口就是JsonArray。
????让我们看看它的常用操作方法:

2.3.1 add —— 往数组中加入value

函数说明

/**
 * 往数组中加入value
 * @param value 值
 * @return bool 是否添加成功,如果返回false一般都是jsonbuffer没有足够的空间
 */
bool add(bool value) const;

bool add(float value) const;
bool add(double value) const;

bool add(signed char value) const;
bool add(signed long value) const;
bool add(signed int value) const;
bool add(signed short value) const;
bool add(unsigned char value) const;
bool add(unsigned long value) const;
bool add(unsigned int value) const;
bool add(unsigned short value) const;

bool add(const char *value) const;
bool add(char *value) const;
bool add(const __FlashStringHelper *value) const;

bool add(const String &value) const;
bool add(const std::string &value) const;

bool add(JsonArray array) const;
bool add(JsonObject object) const;
bool add(JsonVariant variant) const;

例子说明

StaticJsonDocument<200> doc;
JsonArray array = doc.to<JsonArray>();
array.add("hello");
array.add(3.14156);
serializeJson(doc, Serial);

打印结果:

["hello",3.14156]

2.3.2 begin/end —— 返回一个迭代器,可用于数组中的所有对象

函数说明

/**
 * 返回一个迭代器,可用于数组中的所有对象
 * @return iterator
 */
JsonArray::iterator begin() const;
JsonArray::iterator end() const;

例子说明

char json[] = "[\"one\",\"two\",\"three\"]";
DynamicJsonDocument doc(1024);
deserializeJson(doc, json);
JsonArray arr = doc.as<JsonArray>();

// using C++11 syntax (preferred):
for (JsonVariant value : arr) {
    Serial.println(value.as<char*>());
}

// using C++98 syntax (for older compilers):
for (JsonArray::iterator it=arr.begin(); it!=arr.end(); ++it) {
    Serial.println(it->as<char*>());
}

打印结果:

one
two
three

2.3.3 createNestedArray —— 添加json数组

函数说明

/**
 * 添加json数组
 * @return  JsonArray json数组
 */
JsonArray createNestedArray() const;

例子说明

StaticJsonDocument<200> doc;
JsonArray array = doc.to<JsonArray>();
array.add("hello");
JsonArray nested = array.createNestedArray();
nested.add("world");
serializeJson(array, Serial);

打印结果:

["hello",["world"]]

2.3.4 createNestedObject —— 添加json对象

函数说明

/**
 * 添加json对象
 * @return  JsonObject json对象
 */
JsonObject createNestedObject() const;

例子说明

StaticJsonDocument<200> doc;
JsonArray array = doc.to<JsonArray>();
JsonObject nested = array.createNestedObject();
nested["hello"] = "world";
serializeJson(array, Serial);

打印结果:

[{"hello":"world"}]

2.3.5 getElement —— 获取对应index的值

函数说明

/**
 * 获取对应index的值
 */
JsonVariant getElement(size_t index) const;;

2.3.6 isNull —— 判断json数组是否为空

函数说明

/**
 * 判断json数组是否为空
 * @Note You can use this function to:
 *   check if the array was successfully parsed, or
 *   check if the array was successfully allocated.
 */
bool isNull() const;

例子说明

//Example 1: parsing success:
StaticJsonDocument<200> doc;
deserializeJson(doc, "[1,2]");
JsonArray array = doc.as<JsonArray>();
Serial.println(array.isNull()); // false

//Example 2: parsing failure:
StaticJsonDocument<200> doc;
deserializeJson(doc, "{1,2}");
JsonArray array = doc.as<JsonArray>();
Serial.println(array.isNull()); // true

//Example 3: allocation success:
StaticJsonDocument<200> doc;
JsonArray array = doc.to<JsonArray>();
Serial.println(array.isNull()); // false

//Example 4: allocation failure:
StaticJsonDocument<1> doc;
JsonArray array = doc.to<JsonArray>();
Serial.println(array.isNull()); // true

2.3.7 operator[] —— set/get快捷方式

函数说明

/**
 * set/get快捷方式
 */
ElementProxy operator[](size_t index) const;

例子说明

//以下两句代码含义一样
JsonVariant value = array[0];
JsonVariant value = array.getElement(0);

//以下两句代码含义一样
array[0] = "value";
array.getElement(0).set("value");

JsonArray array = doc.to<JsonArray>();
array.add(42);
int value = array[0];
array[0] = 666;

2.3.8 remove —— 移除某一个index位置的元素

函数说明

/**
 * 移除某一个index位置的元素
 * @param index 索引
 */
void remove(size_t index) const;

例子说明

JsonArray array = doc.to<JsonArray>();
array.add("A");
array.add("B");
array.add("C");
array.remove(1);
serializeJson(array, Serial);

打印结果:

["A","C"]

注意

  • 该方法只会移除索引对应的value,但是并不会释放对应的jsonDocument空间,也不建议在循环中同时add和remove;

2.3.9 set —— 用另一个jsonArray代替当前jsonArray

函数说明

/**
 *用另一个jsonArray代替当前jsonArray
 */
bool set(JsonArrayConst src) const;

2.3.10 size —— 返回json数组元素的个数

函数说明

/**
 * 返回json数组元素的个数
 * @return size_t 个数
 */
size_t size() const;

例子说明

JsonArray array = doc.to<JsonArray>();
array.add("hello");
array.add("world");
Serial.println(array.size()); // 2

3.实验代码

3.1 编码Json字符串

实验材料

  • Arduino板子,博主这里用Mega2560

例子代码

/**
 * 编写Json字符串
 * @author 单片机菜鸟
 * @date 2019/06/02
 */
#include <ArduinoJson.h>

void setup() {
  Serial.begin(115200);
  while (!Serial) continue;
  // Json对象对象树的内存工具 静态buffer
  // 200 是大小 如果这个Json对象更加复杂,那么就需要根据需要去增加这个值.
  StaticJsonDocument<200> doc;
  // StaticJsonDocument 在栈区分配内存   它也可以被 StaticJsonDocument(内存在堆区分配) 代替
  // DynamicJsonDocument  doc(200);
  // Add values in the document
  //
  doc["sensor"] = "gps";
  doc["time"] = 1351824120;

  // Add an array.
  //
  JsonArray data = doc.createNestedArray("data");
  data.add(48.756080);
  data.add(2.302038);

  // Generate the minified JSON and send it to the Serial port.
  //
  serializeJson(doc, Serial);
  // The above line prints:
  // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
  // Start a new line
  Serial.println();
  // The above line prints:
  // {
  //   "sensor": "gps",
  //   "time": 1351824120,
  //   "data": [
  //     48.756080,
  //     2.302038
  //   ]
  // }
}

void loop() {
  // not used in this example
}

3.2 解码Json字符串

实验材料

  • Arduino板子,博主这里用Mega2560

例子代码

/**
 * 解析Json字符串
 * @author 单片机菜鸟
 * @date 2019/06/02
 */
#include <ArduinoJson.h>

void setup() {
  Serial.begin(115200);
  while (!Serial) continue;
  // Json对象对象树的内存工具 静态buffer
  // 200 是大小 如果这个Json对象更加复杂,那么就需要根据需要去增加这个值.
  StaticJsonDocument<200> doc;
  // StaticJsonDocument 在栈区分配内存   它也可以被 StaticJsonDocument(内存在堆区分配) 代替
  // DynamicJsonDocument  doc(200);
  char json[] =
      "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";

  // Add an array.
  //
  // Deserialize the JSON document
  DeserializationError error = deserializeJson(doc, json);

  // Test if parsing succeeds.
  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.c_str());
    return;
  }
  // Fetch values.
  //
  // Most of the time, you can rely on the implicit casts.
  // In other case, you can do doc["time"].as<long>();
  const char* sensor = doc["sensor"];
  long time = doc["time"];
  double latitude = doc["data"][0];
  double longitude = doc["data"][1];

  // Print values.
  Serial.println(sensor);
  Serial.println(time);
  Serial.println(latitude, 6);
  Serial.println(longitude, 6);
}

void loop() {
  // not used in this example
}

注意

  • 解析失败通常有如下三个原因:
  1. Json字符串非法(格式不对)
  2. Json字符串产生对象
  3. JsonDocument太小

4. ArduinoJson V6版本编译配置

请参考V5版本说明,非常类似。

5.总结

自此,V5和V6版本已经讲解完毕,往读者深入体会一下,其实也是非常简单的用法。

原文地址:https://www.cnblogs.com/danpianjicainiao/p/11048688.html

时间: 2024-10-29 19:08:08

玩转ArduinoJson库 V6版本的相关文章

玩转ArduinoJson库 V5版本

1.前言 ????一直以来,博主的事例代码中都一直使用到JSON数据格式.而很多初学者一直对JSON格式有很大疑惑,所以博主特意分出一篇博文来重点讲解Arduino平台下的JSON库--ArduinoJSON. ????读者需要注意一下几点: ArduinoJSON的Github地址请参考 wiki. ArduinoJSON说明文档可以参考 wiki,博主强烈建议读者可以尝试去阅读这些文档,肯定获益匪浅. ArduinoJSON目前分为两个大版本 V5 和 V6版本(估计很多初学者会经常看到Ar

更换Qt QtEmbedded库的版本出现问题及解决(交叉编译OpenSSL)

近日将QtEmbedded库的版本由4.7.0更新到4.7.4.工具链并未改变,仍为 Target: arm-none-linux-gnueabiConfigured with: ......Thread model: posixgcc version 4.3.2 (Sourcery G++ Lite 2008q3-72) 所有依赖的库根据需要重新下载最新版本编译.现将在此过程中出现的问题及解决方法列出,以供下次移植时参考. 1.browser程序重新编译,在开发板的命令行运行:./browse

ZeroMQ接口函数之 :zmq_version – 返回ZMQ链接库的版本

ZeroMQ 官方地址 :http://api.zeromq.org/4-2:zmq_version zmq_version(3)          ØMQ Manual - ØMQ/4.1.0 Name zmq_version – 返回ZMQ链接库的版本 Synopsis void zmq_version (int *major, int *minor, int *patch); Description zmq_version()函数会将ZMQ库中对应的版本号填到参数major.minor和p

git基础①创建版本库和版本回退

集中式版本控制系统:版本是集中存放在中央服务器的,做项目的时候要先从中央服务器里面取得最新版本,做完项目然后在推送上传到中央服务器进行储存.缺点是没有网络或者是网速不够快,上传和下载文件要很长时间,不方便也不安全. 分布式版本控制系统:在自己电脑上创建一个本地版本库,修改,上传在本地进行就可以,方便快捷,2人协作,可以直接相互推送给对方,就可以看到各自的修改,多人协作 通常也建立个一个中央服务器,但是这个服务器的作用仅仅是用来方便大家的修改,没有也可以一样的工作,只是没有那么方便而已 安装git

&lt;转&gt;JSTL标签库的版本

参考 http://www.bubuko.com/infodetail-1077023.html http://janedoneway.iteye.com/blog/1245949 从来没认为这是个问题,不过最近发现网上关于这方面的资料比较乱,现将自己的了解整理在此,以备查阅. ? 开发团队经常使用jstl标签库,开始也没在意,大家都是简单引入jstl.jar和standard.jar,后来发现这两个包也有版本差别,各项目小组用的不同,在jsp中定义也有差别,还会引起冲突和代码不兼容.于是想在网

1.GIT常用命令-创建版本库和版本回退

一.安装GIT $ git 查看目前系统里面有没有装GIT sudo apt-get install git 安装GIT $ git config --global user.name "Your Name" $ git config --global user.email "[email protected]" 配置用户名称 $ git init 二.创建版本库 把一个文件夹变成一个可以管理的仓库 $ git add readme.txt 添加一个文件到仓库 $

powershell玩转SQL SERVER所有版本

微软发布了最新的powershell for sql server 2016命令行客户端库.文章介绍了与之相关的实用方法. powershell 传教士 原创文章 2016-06-05,2016-06-30改 允许转载,但必须保留名字和出处,否则追究法律责任 powershell,sql server,2016,功能包,客户端,下载 powershell玩sql server就是比powershell玩mysql强! 问:那么问题来了,强在哪? 答:微软给我们做好了powershell+sqls

[转]linux下使用objdump -p 查看库文件版本等信息

方法一: 文件名已经带有版本号: 这种情况下很容易就能够看到软链指向的文件的版本号是 1.0.1 方法二: 当文件名不带版本号时:如下所示使用readelf -a ***.so读取出文件的版本号,不过此时只能读取到主版本号,version:1 方法三: 如果文件名不带版本号,且又想知道具体的版本号的时候怎么办呢? 这时候只能使用傻瓜方法,生成md5值与已知版本号的共享库相对比了. $ md5sum fcrypt.so.1.0.1d097363e391e926fdd1687d17bb1ebf7 f

git远程库代码版本回滚方法

最近使用git时, 造成了远程库代码需要回滚到之前版本的情况,为了解决这个问题查看了很多资料. 问题产生原因: 提交了错误的版本到远程库. 以下是解决的方法, 供大家参考: 1.对本地代码库进行回滚 git log 查看提交历史,找出要回滚到的commit-id git reset --hard commit-id :回滚到commit-id git reset --hard HEAD~3:将最近3次的提交回滚 2.远程代码库回滚 进行这一步的时候遇到了困难,尝试了多种方法, 查看很多资料都提到