C++ JSON读取时如何实现单个属性名大小写不敏感兼容新旧格式
C++ JSON属性名兼容读写实现方案
以下实现基于常用的nlohmann/json库,其他JSON库可复用相同逻辑调整API即可。
方案1:显式新旧属性名映射(性能最优,适用于属性变更规则明确的场景)
明确已知新旧属性名的对应关系时,优先查找新版小写驼峰属性,查找失败再查询旧版属性,无需遍历所有字段。
工具函数实现
#include <nlohmann/json.hpp> using json = nlohmann::json; template<typename T> T get_compat_property(const json& obj, const std::wstring& new_key, const std::wstring& old_key) { // 优先匹配新版小写驼峰属性 if (obj.contains(new_key)) { return obj[new_key].get<T>(); } // 匹配失败回退旧版属性 if (obj.contains(old_key)) { return obj[old_key].get<T>(); } // 保持原有at方法的异常行为,不需要抛异常可改为返回默认值 throw std::out_of_range("Neither new nor old key found"); }
调用示例
原代码:
auto bDog = array[i].at(L"Dog").as_bool();
修改后代码:
auto bDog = get_compat_property<bool>(array[i], L"dog", L"Dog");
方案2:通用大小写不敏感匹配(适用于旧属性名大小写不固定的场景)
如果旧数据的属性名大小写无统一规则(可能出现DOG/dOg等多种变体),可通过大小写转换实现全匹配。
工具函数实现
#include <nlohmann/json.hpp> #include <cctype> #include <algorithm> using json = nlohmann::json; std::wstring str_to_lower(std::wstring s) { std::transform(s.begin(), s.end(), s.begin(), [](wchar_t c) { return std::tolower(c); }); return s; } template<typename T> T get_case_insensitive_property(const json& obj, const std::wstring& new_key) { // 优先完全匹配新版小写驼峰属性,保证新数据读取性能 if (obj.contains(new_key)) { return obj[new_key].get<T>(); } // 完全匹配失败后走大小写不敏感遍历 std::wstring lower_target = str_to_lower(new_key); for (const auto& item : obj.items()) { if (str_to_lower(item.key()) == lower_target) { return item.value().get<T>(); } } throw std::out_of_range("Case-insensitive key not found"); }
调用示例
// 仅需传入新版小写驼峰属性名即可兼容所有大小写变体 auto bDog = get_case_insensitive_property<bool>(array[i], L"dog");
内容的提问来源于stack exchange,提问作者YAS
相关产品推荐
相关产品推荐

