JSON是一种来自Javascript的对象数据的编码格式,现在被广泛用作互联网上的数据交换格式。
json数据类型有bool、double、string、object、array、null
json对象以{key:value,…}格式表示
json数组以[]括起来表示
示例使用
Qt自然也提供了对json的读写支持
相关的类有
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
我们举个例子来看这几个类如何使用
假设我们需要保存一个4画面的ui布局,还有其他一些相关信息。保存json格式如下:
{
"bShowTitle": true,
"fps": 25,
"username": "admin",
"wnds": [
{
"bVisible": true,
"h": 300,
"w": 400,
"wndid": 1,
"x": 0,
"y": 0
},
{
"bVisible": true,
"h": 300,
"w": 400,
"wndid": 2,
"x": 400,
"y": 0
},
{
"bVisible": true,
"h": 300,
"w": 400,
"wndid": 3,
"x": 0,
"y": 300
},
{
"bVisible": true,
"h": 300,
"w": 400,
"wndid": 4,
"x": 400,
"y": 300
}
]
}
我们使用Qt提供的json类来解析和生成这个json文件
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
QJsonDocment的fromJson方法可以解析json字符串,object方法返回json对象,toJson方法构造一个json格式字符串
QJsonObject表示json对象,通过key索引即可得到value,如obj[“username”]
QJsonArray表示json数组,通过size方法可以获取到数组大小,[]索引方法获取到每一个数组元素
QJsonValue用来封装json的数据类型(bool、double、string、object、array、null),并提供了对应的转换方法
bool toBool(bool defaultValue = false) const;
int toInt(int defaultValue = 0) const;
double toDouble(double defaultValue = 0) const;
QString toString() const;
QString toString(const QString &defaultValue) const;
QJsonArray toArray() const;
QJsonArray toArray(const QJsonArray &defaultValue) const;
QJsonObject toObject() const;
源码赏析
主要研究Qt中如何解析json的,QJsonDocument::fromJson会调用Parser::parse
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
首先eatBOM,去掉可能的BOM格式的三个字节
void Parser::eatBOM()
{
// eat UTF-8 byte order mark
uchar utf8bom[3] = { 0xef, 0xbb, 0xbf };
if (end - json > 3 &&
(uchar)json[0] == utf8bom[0] &&
(uchar)json[1] == utf8bom[1] &&
(uchar)json[2] == utf8bom[2])
json += 3;
}
然后nextToken,寻找到下一个记号,记号有{对象}[数组] key:value,“string”在枚举中可以看到定义
enum {
Space = 0x20,
Tab = 0x09,
LineFeed = 0x0a,
Return = 0x0d,
BeginArray = 0x5b,
BeginObject = 0x7b,
EndArray = 0x5d,
EndObject = 0x7d,
NameSeparator = 0x3a,
ValueSeparator = 0x2c,
Quote = 0x22
};
char Parser::nextToken()
{
if (!eatSpace())
return 0;
char token = *json++;
switch (token) {
case BeginArray:
case BeginObject:
case NameSeparator:
case ValueSeparator:
case EndArray:
case EndObject:
eatSpace();
case Quote:
break;
default:
token = 0;
break;
}
return token;
}
// 去掉空格
bool Parser::eatSpace()
{
while (json < end) {
if (*json > Space)
break;
if (*json != Space &&
*json != Tab &&
*json != LineFeed &&
*json != Return)
break;
++json;
}
return (json < end);
}
nextToken遇到对象开始符{
就开始解析对象parseObject,遇到数组开始符[
就解析数组parseArray.
parseObject和parseArray的过程类似,遇到标识符就解析对应的东西,主要有解析值parseValue,解析字符串parseArray,解析数字parseNumber。有兴趣的可以深挖下源码。