11

我正在使用 jsoncpp 从 JSON 文件中读取设置。

我想要两个级联设置文件,比如MasterSettings.jsonLocalSettingsLocalSettings.json是 MasterSettings 的子集。我想先加载 MasterSettings,然后再加载 LocalSettings。如果 LocalSettings 的值与 MasterSettings 不同,则该值将覆盖 MasterSettings 中的值。很像 CSS 中的级联。

有没有什么优雅的方法可以用 jsoncpp 做到这一点?

4

2 回答 2

14

我将假设您的设置文件是 JSON 对象。

如此处所示,当 JSONCpp 解析文件时,它会清除根节点的内容。这意味着尝试在旧文件之上解析新文件不会保留旧数据。但是,如果您将两个文件解析为单独的 Json::Value 节点,则可以直接通过使用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];
        }
    }
}
于 2014-05-25T21:14:52.213 回答
1

我知道已经有一段时间了。但...

除了正确答案和注释之外,这里有一个代码版本,供那些使用旧 g++ 版本的人使用:

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();                                                                                                  
}
于 2021-08-19T14:23:55.030 回答