Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • A ArduinoJson
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 24
    • Issues 24
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Benoît Blanchon
  • ArduinoJson
  • Issues
  • #821
Closed
Open
Issue created Sep 28, 2018 by Christof Dallermassl@cdaller

add json path functionality to extract values

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;
}
Assignee
Assign to
Time tracking