Search code examples
c++jsonjsoncpp

Is there an elegant way to cascade-merge two JSON trees using jsoncpp?


I am using jsoncpp to read settings from a JSON file.

I would like to have two cascading settings file, say MasterSettings.json and LocalSettings.json where LocalSettings is a subset of MasterSettings. I would like to load MasterSettings first and then LocalSettings. Where LocalSettings has a value that differs from MasterSettings, that value would overwrite the one from MasterSettings. Much like the cascade in CSS.

Is there any elegant way to do this with jsoncpp?


Solution

  • I'm going to assume your settings files are JSON objects.

    As seen here, when JSONCpp parses a file, it clears the contents of the root node. This mean that trying to parse a new file on top of the old one won't preserve the old data. However, if you parse both files into separate Json::Value nodes, it's straight forward to recursively copy the values yourself by iterating over the keys in the second object using getMemberNames.

    // Recursively copy the values of b into a. Both a and b must be objects.
    void update(Json::Value& a, Json::Value& b) {
        if (!a.isObject() || !b.isObject()) return;
    
        for (const auto& key : b.getMemberNames()) {
            if (a[key].isObject()) {
                update(a[key], b[key]);
            } else {
                a[key] = b[key];
            }
        }
    }