Open
Description
I have an application that fetches a json file from an http server and extracts a value from the json. The url (and therefore the structure of the json) is configurable during runtime. So I wanted to use a json path to define which value to extract from the json content. I googled, but could not find any, so I wrote a very simple jsonPath parser.
I think a method like this would be quite useful in the library - what do you think?
As I am not very experienced in C++, the method could (and probably should) be rewritten before being integrated :-)
// parse jsonPaths like $.foo[1].bar.baz[2][3].value (equals to foo[1].bar.baz[2][3].value)
float parseJson(char* jsonString, char *jsonPath) {
float jsonValue;
DynamicJsonBuffer jsonBuffer;
JsonVariant root = jsonBuffer.parse(jsonString);
JsonVariant element = root;
if (root.success()) {
// parse jsonPath and navigate through json object:
char pathElement[40];
int pathIndex = 0;
printf("parsing '%s'\n", jsonPath);
for (int i = 0; jsonPath[i] != '\0'; i++){
if (jsonPath[i] == '$') {
element = root;
} else if (jsonPath[i] == '.') {
if (pathIndex > 0) {
pathElement[pathIndex++] = '\0';
// printf("pathElement '%s'\n", pathElement);
pathIndex = 0;
element = element[pathElement];
if (!element.success()) {
printf("failed to parse key %s\n", pathElement);
}
}
} 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++] = '\0';
// printf("pathElement '%s'\n", pathElement);
pathIndex = 0;
element = element[pathElement];
if (!element.success()) {
printf("failed in parsing key %s\n", pathElement);
}
}
} else if (jsonPath[i] == ']') {
pathElement[pathIndex++] = '\0';
int arrayIndex = strtod(pathElement, NULL);
// printf("index '%s' = %d\n", pathElement, arrayIndex);
pathIndex = 0;
element = element[arrayIndex];
if (!element.success()) {
printf("failed in parsing index %d\n", arrayIndex);
}
}
}
// final token if any:
if (pathIndex > 0) {
pathElement[pathIndex++] = '\0';
// printf("pathElement '%s'\n", pathElement);
pathIndex = 0;
element = element[pathElement];
if (!element.success()) {
printf("failed in parsing key %s\n", pathElement);
}
}
jsonValue = element.as<float>();
//jsonValue = measurements[1]["sensordatavalues"][0]["value"];
printf("success reading value: %f\n", jsonValue);
} else {
jsonValue = -1; // should be NaN or something similar
printf("could not parse json for value");
}
return jsonValue;
}