基于字符串递归输入Json对象
Recursively entering Json object based on string
我有以下json对象:
{
"ESP_IN_PC_OUT":{
"track":{
"1":{
"mute":{
"type":"LED",
"pins":[4]
}
},
"2":{
"mute":{
"type":"LED",
"pins":[5]
}
}
}
}
}
我想输入对象,取决于格式为"/index1/index2/index3…"的字符串。(字符串是OSC消息的地址)。例如,"/track/2/mute"应该返回一个Json对象,如下所示:
{
"type":"LED",
"pins":[5]
}
这样我就可以访问类型、pins数组和其他一些稍后将实现的值。
我在ESP8266上使用Arduino JSON库。这是我试过的代码:
#include <ArduinoJson.h>
char *jsonstr = "{n "ESP_IN_PC_OUT":{n "track":{n "1":{n "mute":{n "type":"LED",n "pins":[4]n }n },n "2":{n "mute":{n "type":"LED",n "pins":[5]n }n }n }n },nnn "ESP_OUT_PC_IN":{n "analog":{n },n "digital":{n "16":"/track/1/mute"n }n }n}";
void setup() {
Serial.begin(115200);
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(jsonstr);
if (!root.success()) {
Serial.println("parseObject() failed");
return;
}
Serial.println((const char*) root["ESP_IN_PC_OUT"]["track"]["2"]["mute"]["type"]); // prints "LED"
Serial.println();
char *address = "/track/2/mute"; // _____Interesting part_____
char *tmp = strtok(address,"/");
JsonObject& tmpJson = root["ESP_IN_PC_OUT"];
bool success = true;
while(tmp != NULL && success == true){
Serial.println(tmp);
if(tmpJson.containsKey(tmp)){
tmpJson = tmpJson[tmp]; // Error: use of deleted function 'ArduinoJson::JsonObject& ArduinoJson::JsonObject::operator=(const ArduinoJson::JsonObject&)'
tmp = strtok(NULL,"/");
} else {
success = false;
}
}
if(success == true){
Serial.println((const char*)tmpJson["type"]);
} else {
Serial.println("Address not found");
}
}
void loop() {
}
然而,这给了我以下错误消息:
JSON_OSC_settings2:26: error: use of deleted function 'ArduinoJson::JsonObject& ArduinoJson::JsonObject::operator=(const ArduinoJson::JsonObject&)'
tmpJson = tmpJson[tmp];
^
In file included from C:UsersPieterDocumentsArduinolibrariesArduinoJson-master/include/ArduinoJson.hpp:12:0,
from C:UsersPieterDocumentsArduinolibrariesArduinoJson-master/include/ArduinoJson.h:8,
from C:UsersPieterDocumentsArduinolibrariesArduinoJson-master/ArduinoJson.h:8,
from C:UsersPieterDocumentsArduinoJSON_OSC_settings2JSON_OSC_settings2.ino:1:
C:UsersPieterDocumentsArduinolibrariesArduinoJson-master/include/ArduinoJson/JsonObject.hpp:38:7: note: 'ArduinoJson::JsonObject& ArduinoJson::JsonObject::operator=(const ArduinoJson::JsonObject&)' is implicitly deleted because the default definition would be ill-formed:
class JsonObject : public Internals::JsonPrintable<JsonObject>,
^
In file included from C:UsersPieterDocumentsArduinolibrariesArduinoJson-master/include/ArduinoJson/JsonArray.hpp:13:0,
from C:UsersPieterDocumentsArduinolibrariesArduinoJson-master/include/ArduinoJson.hpp:11,
from C:UsersPieterDocumentsArduinolibrariesArduinoJson-master/include/ArduinoJson.h:8,
from C:UsersPieterDocumentsArduinolibrariesArduinoJson-master/ArduinoJson.h:8,
from C:UsersPieterDocumentsArduinoJSON_OSC_settings2JSON_OSC_settings2.ino:1:
C:UsersPieterDocumentsArduinolibrariesArduinoJson-master/include/ArduinoJson/Internals/ReferenceType.hpp:32:18: error: 'ArduinoJson::Internals::ReferenceType& ArduinoJson::Internals::ReferenceType::operator=(const ArduinoJson::Internals::ReferenceType&)' is private
ReferenceType& operator=(const ReferenceType&);
^
In file included from C:UsersPieterDocumentsArduinolibrariesArduinoJson-master/include/ArduinoJson.hpp:12:0,
from C:UsersPieterDocumentsArduinolibrariesArduinoJson-master/include/ArduinoJson.h:8,
from C:UsersPieterDocumentsArduinolibrariesArduinoJson-master/ArduinoJson.h:8,
from C:UsersPieterDocumentsArduinoJSON_OSC_settings2JSON_OSC_settings2.ino:1:
C:UsersPieterDocumentsArduinolibrariesArduinoJson-master/include/ArduinoJson/JsonObject.hpp:38:7: error: within this context
class JsonObject : public Internals::JsonPrintable<JsonObject>,
^
exit status 1
use of deleted function 'ArduinoJson::JsonObject& ArduinoJson::JsonObject::operator=(const ArduinoJson::JsonObject&)'
我该如何解决这个问题?我可以采取什么不同的方法?
我编写了一个函数来解析简单的json路径字符串并从json字符串中提取值。详见https://github.com/bblanchon/ArduinoJson/issues/821
我最近将它改编为ArduinoJson6 -我不得不承认我不是一个c++家伙,所以请宽恕我的代码:
// parse jsonPaths like $.foo[1].bar.baz[2][3].value equals to foo[1].bar.baz[2][3].value
String parseJson(char* jsonString, char *jsonPath) {
Serial.printf("parsing String '%s'n", jsonString);
String jsonValue;
DynamicJsonDocument jsonBuffer(64000); // fixme!!!!
DeserializationError err = deserializeJson(jsonBuffer, jsonString);
JsonVariant root = jsonBuffer.as<JsonVariant>();
JsonVariant element = root;
if (!err) {
// parse jsonPath and navigate through json object:
char pathElement[40];
int pathIndex = 0;
Serial.printf("parsing Path '%s'n", jsonPath);
for (int i = 0; jsonPath[i] != ' '; i++){
if (jsonPath[i] == '$') {
element = root;
} else if (jsonPath[i] == '.') {
if (pathIndex > 0) {
pathElement[pathIndex++] = ' ';
//printf("pathElement '%s'n", pathElement);
pathIndex = 0;
element = element[pathElement];
if (element == nullptr) {
Serial.printf("failed to parse key %sn", pathElement);
return nullptr;
}
}
} else if ((jsonPath[i] >= 'a' && jsonPath[i] <= 'z')
|| (jsonPath[i] >= 'A' && jsonPath[i] <= 'Z')
|| (jsonPath[i] >= '0' && jsonPath[i] <= '9')
|| jsonPath[i] == '-' || jsonPath[i] == '_'
) {
pathElement[pathIndex++] = jsonPath[i];
} else if (jsonPath[i] == '[') {
if (pathIndex > 0) {
pathElement[pathIndex++] = ' ';
// printf("pathElement '%s'n", pathElement);
pathIndex = 0;
element = element[pathElement];
if (element == nullptr) {
Serial.printf("failed in parsing key %sn", pathElement);
return nullptr;
}
}
} else if (jsonPath[i] == ']') {
pathElement[pathIndex++] = ' ';
int arrayIndex = strtod(pathElement, NULL);
// printf("index '%s' = %dn", pathElement, arrayIndex);
pathIndex = 0;
element = element[arrayIndex];
if (element == nullptr) {
Serial.printf("failed in parsing index %dn", arrayIndex);
return nullptr;
}
}
}
// final token if any:
if (pathIndex > 0) {
pathElement[pathIndex++] = ' ';
// printf("pathElement '%s'n", pathElement);
pathIndex = 0;
element = element[pathElement];
if (element == nullptr) {
Serial.printf("failed in parsing key %sn", pathElement);
return nullptr;
}
}
jsonValue = element.as<String>();
} else {
jsonValue = nullptr;
}
return jsonValue;
}
我不是C开发人员,但是可以帮助您的是所谓的»JSONPath«,它意味着JSON的xPath对应。也许你可以找到一个可以这样做的库。
这似乎是类似的事情。
为了指向子对象,您可以简单地使用:
JsonObject& tmpJson = root["ESP_IN_PC_OUT"]["track"]["2"]["mute"];
接下来,您可以检查此子对象是否存在,将其与JsonObject::invalid
进行比较,如下所示:
bool success = (tmpJson != JsonObject::invalid());
if(success == true){
Serial.println((const char*)tmpJson["type"]);
} else {
Serial.println("Address not found");
}
如果路径的一部分不存在,operator[]
将返回对JsonObject::invalid
的引用,然后访问它的子节点也将返回对JsonObject::invalid
的引用,那么迭代到不存在的子节点是安全的。
相关文章:
- 有没有办法让编译器在我放置字符串而不是 nlohmann::json 对象时抛出错误?
- 如何使用 picojson.h 在 c++ 中从头开始创建 json 对象
- .value( "key" , default) 不适用于空的 json 对象吗?
- Rapidjson 遍历并获取复杂 JSON 对象成员的值
- JSON对象到C++模型
- 使用 NLOHMANN JSON 在 C++ 中创建嵌套的 JSON 对象
- 如何在 c++ 中从两个向量创建 JSON 对象?
- 如何正确解析 Java+C++ TCP 连接中的 JSON 对象?
- 如何将矢量转换为 json 对象?C++
- 将C++具有 150+ 变量的类转换为 Json 对象
- Poco 迭代嵌套的 JSON 对象
- 如何提取由特定模式分开的JSON对象字符串
- 如何创建具有分层对象和值的 json 对象
- 将 JSON 对象作为参数在 JNI 中传递给 CPP,并在 CPP 中检索 JSON 对象的数据
- 无法区分 JSON 对象/数组/字符串
- 如何将 cpr 的获取响应转换为 json 对象?
- 我正在尝试打开一个 json 文件.并将其存储为 JSON 对象
- 如何在不更改 C++ 中的值的情况下更改 json 对象名称
- 如何将Nolhmann JSON对象分成字符串
- Cpp:Cpp中的JSON解析器,提供支持序列化/反序列化功能,将JSON对象转换为用户定义的类