参考这篇文章,并进行了改进
使用QT遍历Json文档及搜索子对象_黑脚印_DarkSpoor的博客-CSDN博客
class JsonTools
{
public:
JsonTools(){m_printable=false;m_newValue=nullptr;}
public:
void LoadJsonFromFile(const QString& jsonfilename,QJsonDocument& jsDoc)
{
QFile file(jsonfilename);
file.open(QIODevice::ReadWrite);
QByteArray json = file.readAll();
jsDoc = QJsonDocument::fromJson(json);
}
void PrintJson(const QJsonDocument& jDoc)
{
m_printable = true;
auto jsDoc = jDoc;
LoopJson(jsDoc);
m_printable = false;
}
QList<QJsonValue> findByKey(const QJsonDocument& jDoc, const QString &key)
{
this->m_searchResultList.clear();
this->m_searchString = key;
auto jsDoc = jDoc;
LoopJson(jsDoc);
QList<QJsonValue> objList = m_searchResultList;
return objList;
}
void replaceValue(QJsonDocument& jDoc, const QString &key, const QJsonValue &value)
{
this->m_searchResultList.clear();
this->m_newValue = &value;
LoopJson(jDoc);
this->m_newValue = nullptr;
}
private:
void LoopJson(QJsonDocument& jDoc)
{
if(jDoc.isObject())
{
QJsonObject jObject = jDoc.object();
LoopJsonObject(jObject,"根");
jDoc.setObject(jObject);
}
else if(jDoc.isArray())
{
QJsonArray jArray = jDoc.array();
LoopJsonArray(jArray,"根");
jDoc.setArray(jArray);
}
else if(jDoc.isEmpty())
{
//空文档
qDebug() << "空文档";
}
}
void LoopJsonObject(QJsonObject& obj,const QString& key,int retract=0)
{
//输出使用的缩进
QString tabs = "";
for(int i=0;i<retract;++i) {tabs+="\t";}
if (m_printable)
{
qDebug().noquote() << tabs << key << "是object,有" << obj.size() << "个子元素";
}
for(const QString& key: obj.keys())
{
QJsonValue jvalue = obj[key];
LoopJsonValue(jvalue,key,retract+1);
obj[key] = jvalue;
}
}
void LoopJsonArray(QJsonArray& arr,const QString& key,int retract=0)
{
//输出使用的缩进
QString tabs = "";
for(int i=0;i<retract;++i) {tabs+="\t";}
if (m_printable)
{
qDebug().noquote() << tabs << key << "是Array,有" << arr.size() << "个子元素";
}
for(QJsonArray::iterator it=arr.begin();it!=arr.end();++it)
{
QJsonValue jvalue = *it;
LoopJsonValue(jvalue,"",retract+1);
*it = jvalue;
}
}
void LoopJsonValue(QJsonValue& jvalue,const QString& key,int retract=0)
{
//输出使用的缩进
QString tabs = "";
for(int i=0;i<retract;++i) {tabs+="\t";}
if (key == m_searchString)
{
this->m_searchResultList.append(jvalue);
if (this->m_newValue != nullptr)
{
jvalue = *(this->m_newValue);
return;
}
}
if(jvalue.isArray())
{
QJsonArray childArray = jvalue.toArray();
LoopJsonArray(childArray,key,retract);
jvalue = QJsonValue(childArray);
}
else if(jvalue.isObject())
{
QJsonObject childObject = jvalue.toObject();
LoopJsonObject(childObject,key,retract);
jvalue = QJsonValue(childObject);
}
else if(jvalue.isBool())
{
if (m_printable)
{
qDebug().noquote() << tabs << key << " 是bool: " << jvalue.toBool();
}
}
else if(jvalue.isDouble())
{
if (m_printable)
{
qDebug().noquote() << tabs << key << " 是double: " << jvalue.toDouble();
}
}
else if(jvalue.isString())
{
if (m_printable)
{
qDebug().noquote() << tabs << key << " 是string: " << jvalue.toString();
}
}
else if(jvalue.isUndefined())
{
if (m_printable)
{
qDebug().noquote() << tabs << " 未定义 ";
}
}
else if(jvalue.isNull())
{
if (m_printable)
{
qDebug() << tabs << " is Null ";
}
}
}
private:
bool m_printable;
QList<QJsonValue> m_searchResultList;
QString m_searchString;
const QJsonValue *m_newValue;
};
用法示例
QString jsonData = "{\
\"type\": \"Implementation\",\
\"Implementation\": \
[\
{\
\"name\": \"Steer\",\
\"module\": \"SteerHeat\",\
\"methods\": [],\
\"events\": \
[\
{\
\"Notifier\": \"add\",\
\"name\": \"Steer_Notifier\",\
\"params\": \
[\
{\
\"name\": \"SteerSt\",\
\"type\": \"SteerEnum\",\
\"standard type\": \"uint8_t\",\
\"min value\": 0,\
\"max value\": 1,\
\"value\": \"-\",\
\"key\": true\
}\
]\
}\
]\
},\
{\
\"name\": \"SteerCtrl\",\
\"module\": \"Heat\",\
\"methods\": \
[\
{\
\"name\": \"HeatCtrl\",\
\"params\": \
[\
{\
\"name\": \"Response\",\
\"type\": \"Response\",\
\"standard type\": \"uint8_t\",\
\"min value\": 0,\
\"max value\": 1,\
\"value\": \"-\"\
}\
]\
}\
]\
}\
]\
}";
QByteArray jsonDataByte = jsonData.toUtf8().data();
JsonTools zjson;
QJsonDocument m_implementationDoc = QJsonDocument::fromJson(jsonDataByte, &jsError);
//查找
QList<QJsonValue> resList = zjson.findByKey(m_implementationDoc, "module");
//替换
QJsonValue value(666);
zjson.replaceValue(m_implementationDoc, "module", value);
//遍历
zjson.PrintJson(m_implementationDoc);