Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update nested value in multi hierarchy json object #1084

Closed
haseebmazhar-aai opened this issue May 10, 2018 · 5 comments
Closed

update nested value in multi hierarchy json object #1084

haseebmazhar-aai opened this issue May 10, 2018 · 5 comments
Labels
solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@haseebmazhar-aai
Copy link

Hi, I was trying to integrate nlohmann json library in our project. I was stuck in an issue and could not find any workaround. The issue is I did not know about the level of JSON data and depending upon the key, I have to update the value and return the whole JSON object. The key and data can be of any level.
My json data would be like this
"logger": { "channels": { "log_configure": "acquired" }}
key would be like this logger.channels.log_configure.
I have to change the value of above key to "not acquired".
Is this functionality currently supported?

@gregmarr
Copy link
Contributor

You could parse apart the key and do the lookup yourself, or you could transform the key to use the JSONPath functionality.

@nlohmann
Copy link
Owner

Indeed JSON Pointers could help here. See https://nlohmann.github.io/json/classnlohmann_1_1basic__json_ac6946dffeb3be5aa173645f0467a44b3.html#ac6946dffeb3be5aa173645f0467a44b3 for the respective operator and https://tools.ietf.org/html/rfc6901 for the specification.

@nlohmann nlohmann added the solution: proposed fix a fix for the issue has been proposed and waits for confirmation label May 11, 2018
@haseebmazhar-aai
Copy link
Author

@nlohmann but JSON pointer uses "" operator. So we have to use static key inside double quotes for JSON pointers, which in my case would be dynamic. Also in my requirements If the input key is logger.channels.log_configure and json data is "logger": { }. Then I have to create a new dictionary object "channels" inside logger and then set value of log_configure inside it. so I think I have to create this functionality manually.

@nlohmann
Copy link
Owner

You can actually create a JSON Pointer from a string. Here is a complete example that could help you:

#include <iostream>
#include "json.hpp"

using json = nlohmann::json;
using json_pointer = nlohmann::json::json_pointer;

// from json.hpp
void replace_substring(std::string& s, const std::string& f, const std::string& t)
{
    assert(not f.empty());
    for (auto pos = s.find(f);             // find first occurrence of f
         pos != std::string::npos;         // make sure f was found
         s.replace(pos, f.size(), t),      // replace with t, and
         pos = s.find(f, pos + t.size()))  // find next occurrence of f
    {}
}

int main() {
    // your JSON value
    json j = R"( {"logger": { "channels": { "log_configure": "acquired" }}} )"_json;
    // the "Pointer"
    std::string ptr = "logger.channels.log_configure";
    
    // change ptr to a real JSON Pointer
    replace_substring(ptr, ".", "/");
    ptr = "/" + ptr;
    
    // access the value
    std::cout << j.at(json_pointer(ptr)) << std::endl;
}

@haseebmazhar-aai
Copy link
Author

@nlohmann got it, Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

No branches or pull requests

3 participants