开发工作中涉及JSON文件的解析/编码是不可避免的,象PHP/JAVA/C#等语言中都内置有非常方便的JSON操作类库,但C++自身没有提供这样的操作方法,因此不得不借助一些第三方库来完成JSON操作。之前使用过jsoncpp,感觉不是太好,对于一些含有特殊字符的json内容解析时还可能发生程序崩溃,后来接触到RadpidJSON,发现非常不错,据官方宣称是最快的JSON库,所以称之为"RAPID"。
下面是本人在工作中封装的工具函数,使用非常方便,能够满足大多数情况下JSON操作的需要,能够大节省我们的编码时间。
struct TStrMapVec
{
vector> 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<:map>>& 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<: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 m_mapParams;
map 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 mapParams;
for (size_t i = 0; 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