Is there an elegant way to cascade-merge two JSON trees using jsoncpp?
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]; } }}
I know it has been a while. but...
In addition to the correct answer and the commentary, here is a code version for those who use a older g++ version:
void jsonMerge(Json::Value &a, Json::Value &b) { if (!a.isObject() || !b.isObject()) return; vector<string> member_name = b.getMemberNames(); string key = ""; for (unsigned i = 0, len = member_name.size(); i < len; i++) { key = member_name[i]; if (!a[key].isNull() && a[key].type() == Json::objectValue && b[key].type() == Json::objectValue) { jsonMerge(a[key], b[key]); } else { a[key] = b[key]; } } member_name.clear(); }