JSON文件
json在网络通信中经常被使用,特别是在与 pyhton、java服务交互时,常常要求传递、解析 json。
json文件格式
json标准符号
1.花括号
{}
2.双引号
""
3.冒号
:
4.逗号
,
5.中括号
[]
json示例
{
"id" : 1,
"name" : "Tim",
"isFemal" : false
,
"relevant" : null
,
"children" : ["Jack","John","James"],
"address" : {
"street" : "Wiessenstrasse",
"postCode" : 100001
}
}
其中,id 为数值,name 为字符串,isFemal为布尔值,relevant为空,children为数组,address为对象。
json解析
这里使用QT中的 QJson模块来解析、构造 json。
struct JsonPrivate
{
JsonPrivate(const QString
&jsonOrJsonFilePath
, bool fromFile
);
void setValue(QJsonObject
&parent
, const QString
&path
, const QJsonValue
&newValue
);
QJsonValue
getValue(const QString
&path
, const QJsonObject
&fromNode
) const;
QJsonObject root
;
QJsonDocument doc
;
bool valid
= true
;
QString errorString
;
};
JsonPrivate
::JsonPrivate(const QString
&jsonOrJsonFilePath
, bool fromFile
) {
QByteArray
json("{}");
if (fromFile
) {
QFile
file(jsonOrJsonFilePath
);
if (file
.open(QIODevice
::ReadOnly
| QIODevice
::Text
)) {
json
= file
.readAll();
} else {
valid
= false
;
errorString
= QString("Cannot open the file: %1").arg(jsonOrJsonFilePath
);
qDebug() << errorString
;
return;
}
} else {
json
= jsonOrJsonFilePath
.toUtf8();
}
QJsonParseError error
;
doc
= QJsonDocument
::fromJson(json
, &error
);
if (QJsonParseError
::NoError
== error
.error
) {
root
= doc
.object();
} else {
valid
= false
;
errorString
= QString("%1\nOffset: %2").arg(error
.errorString()).arg(error
.offset
);
qDebug() << errorString
;
}
}
属性值读取
QJsonValue JsonPrivate
::getValue(const QString
&path
, const QJsonObject
&fromNode
) const {
QJsonObject parent
= fromNode
.isEmpty() ? root
: fromNode
;
QStringList names
= path
.split(QRegularExpression("\\."));
int size
= names
.size();
for (int i
= 0; i
< size
- 1; ++i
) {
if (parent
.isEmpty()) {
return QJsonValue();
}
parent
= parent
.value(names
.at(i
)).toObject();
}
return parent
.value(names
.last());
}
属性值设置
void JsonPrivate
::setValue(QJsonObject
&parent
, const QString
&path
, const QJsonValue
&newValue
) {
const int indexOfDot
= path
.indexOf('.');
const QString property
= path
.left(indexOfDot
);
const QString restPath
= (indexOfDot
> 0) ? path
.mid(indexOfDot
+ 1) : QString();
QJsonValue fieldValue
= parent
[property
];
if(restPath
.isEmpty()) {
fieldValue
= newValue
;
} else {
QJsonObject obj
= fieldValue
.toObject();
setValue(obj
, restPath
, newValue
);
fieldValue
= obj
;
}
parent
[property
] = fieldValue
;
}
有了 JsonPrivate 模块,我们就可以很方便的读取、修改 json文件了。 对于示例中的json,我们可以这样去读取、修改:
读取
JsonPrivate
jsonUtil(jsonString
,false
);
int idValue
= jsonUtil
.getValue("id").toInt();
QString nameValue
= jsonUtil
.getValue("name").toString();
bool isFemalValue
= jsonUtil
.getValue("isFemal").toBool();
QStringList childrenList
;
QJsonArray array
= jsonUtil
.getValue("children").toArray();
for (QJsonArray
::const_iterator iter
= array
.begin(); iter
!= array
.end(); ++iter
) {
QJsonValue value
= *iter
;
childrenList
<< value
.toString();
}
QString streetValue
= jsonUtil
.getValue("address.street").toString();
int postCodeValue
= jsonUtil
.getValue("address.postCode").toInt();
修改
JsonPrivate
jsonUtil(jsonString
, false
);
jsonUtil
.setValue(jsonUtil
.root
, "id", 2);
jsonUtil
.setValue(jsonUtil
.root
, "name", "Lily");
jsonUtil
.setValue(jsonUtil
.root
, "isFemal", true
);
QStringList childrenList
= QStringList() << "Kevin" << "Peter";
QJsonArray array
;
foreach(const QString
&str
, childrenList
) {
array
.append(str
);
}
jsonUtil
.setValue(jsonUtil
.root
, "children", array
);
jsonUtil
.setValue(jsonUtil
.root
, "address.street", "BaihuaRoad");
jsonUtil
.setValue(jsonUtil
.root
, "address.postCode", 100002);
完整的文本操作源码,点击此处下载。