开发工作中涉及JSON文件的解析/编码是不可避免的,象PHP/JAVA/C#等语言中都内置有非常方便的JSON操作类库,但C++自身没有提供这样的操作方法,因此不得不借助一些第三方库来完成JSON操作。之前使用过jsoncpp,感觉不是太好,对于一些含有特殊字符的json内容解析时还可能发生程序崩溃,后来接触到RadpidJSON,发现非常不错,据官方宣称是最快的JSON库,所以称之为"RAPID"。
下面是本人在工作中封装的工具函数,使用非常方便,能够满足大多数情况下JSON操作的需要,能够大节省我们的编码时间。
struct TStrMapVec { vector<map<string, string>> vec_; }; struct TJsonParseResult { public: bool FindParam(const std::string& key) { std::string name(key); std::transform(name.begin(), name.end(), name.begin(), ::tolower); auto it = m_mapParams.find(name); if (it != m_mapParams.end()) { return true; } auto it1 = m_mapArray.find(name); if (it1 != m_mapArray.end()) { return true; } return false; } std::string GetParam(const std::string& key) { std::string name(key); std::transform(name.begin(), name.end(), name.begin(), ::tolower); std::string value; auto it = m_mapParams.find(name); if (it != m_mapParams.end()) { value = it->second; } return value; } void GetArrayParam(const std::string& key, std::vector<std::map<std::string, std::string>>& vecParams) { std::string name(key); std::transform(name.begin(), name.end(), name.begin(), ::tolower); auto it = m_mapArray.find(name); if (it != m_mapArray.end()) { vecParams = it->second.vec_; } } void AddParam(const std::string& key, const std::string& value) { std::string name(key); std::transform(name.begin(), name.end(), name.begin(), ::tolower); m_mapParams[name] = value; } void AddArrayParam(const std::string& key, std::map<std::string, std::string>& mapParams) { std::string name(key); std::transform(name.begin(), name.end(), name.begin(), ::tolower); m_mapArray[name].vec_.push_back(mapParams); } void RemoveParam(std::string name) { m_mapParams.erase(name); m_mapArray.erase(name); } bool IsEmpty() { return m_mapParams.empty() && m_mapArray.empty(); } public: map<string, string> m_mapParams; map<string, TStrMapVec> m_mapArray; }; static void ParseJsonObj(const rapidjson::Value& jsonObj, TJsonParseResult& zjapiRes, string namePrefix = "") { if (jsonObj.IsNull() || jsonObj.IsObject() == false) { return; } for (auto it = jsonObj.MemberBegin(); it != jsonObj.MemberEnd(); ++it) { auto key = it->name.GetString(); const rapidjson::Value& jsonValue = it->value; string name = namePrefix; string value; if (name.empty() == false) { name += "."; } name += key; if (jsonValue.IsString() || jsonValue.IsNumber()) { if (jsonValue.IsString()) { value = jsonValue.GetString(); } else if (jsonValue.IsInt()) { value = to_string(jsonValue.GetInt()); } else if (jsonValue.IsUint()) { value = to_string(jsonValue.GetUint()); } else if (jsonValue.IsInt64()) { value = to_string(jsonValue.GetInt64()); } else if (jsonValue.IsUint64()) { value = to_string(jsonValue.GetUint64()); } else if (jsonValue.IsDouble()) { value = to_string(jsonValue.GetDouble()); } zjapiRes.AddParam(name, value); } else if (jsonValue.IsArray()) { //假定为数组时,数组元素只能是类似于{"a":1,"b":2}这样不再包含子数组 map<string, string> mapParams; for (size_t i = 0; i < jsonValue.Size(); i++) { const rapidjson::Value& arrItem = jsonValue[i]; if (arrItem.IsNull() || arrItem.IsObject() == false) { continue; } auto jsonText = std::move(JsonToString(arrItem)); mapParams["json"] = jsonText; for (auto itItemMember = arrItem.MemberBegin(); itItemMember != arrItem.MemberEnd(); ++itItemMember) { auto itemMemberKey = itItemMember->name.GetString(); const rapidjson::Value& jsonItemMemberValue = itItemMember->value; if (jsonItemMemberValue.IsString()) { mapParams[itemMemberKey] = jsonItemMemberValue.GetString(); } else if (jsonItemMemberValue.IsInt()) { mapParams[itemMemberKey] = to_string(jsonItemMemberValue.GetInt()); } else if (jsonItemMemberValue.IsUint()) { mapParams[itemMemberKey] = to_string(jsonItemMemberValue.GetUint()); } else if (jsonItemMemberValue.IsInt64()) { mapParams[itemMemberKey] = to_string(jsonItemMemberValue.GetInt64()); } else if (jsonItemMemberValue.IsUint64()) { mapParams[itemMemberKey] = to_string(jsonItemMemberValue.GetUint64()); } else if (jsonItemMemberValue.IsArray()) { mapParams[itemMemberKey] = std::move(JsonToString(jsonItemMemberValue)); } } zjapiRes.AddArrayParam(name, mapParams); } } else if (jsonValue.IsObject()) { ParseJsonObj(jsonValue, zjapiRes, name); } } } //JSON解析工具函数 void ParseJson(const std::string& jsonRes, TJsonParseResult& jsonparseresult) { rapidjson::Document jsonDoc; jsonDoc.Parse<0>(jsonRes.c_str()); if (jsonDoc.HasParseError()) { rapidjson::ParseErrorCode code = jsonDoc.GetParseError(); return; } ParseJsonObj(jsonDoc, jsonparseresult); } 比如对于json内容{"a":1,"b":2},调用ParseJson后,输出参数jsonparseresult的map中存在2个元素: "a" => 1, "b" => 2