基于“开源json处理库cJSON”,采用Qt进行二次封装,与QByteArray、QVariant类相结合,比Qt5自带的Qt处理库方便简单。

主要特点:

  • 适用于Qt4、Qt5;

  • 无需手动释放内存,解决cJSON内存管理的麻烦;

  • 使用简单,只有两个类json_object、json_array,本身就支持序列化和反序列化,无需专门的json_document类;

  • 使用方便,只需要添加cJSON 和 QJSON总共4个文件;

简述

Qt5 中包含了处理 JSON 的类,均以 QJson 开头(例如:QJsonDocument、QJsonArray、QJsonObject),在 QtCore 模块中,不需要额外引入其它模块。

常用的 JSON 库

json.org 中介绍了 JSON 在各种语言中的应用,在 C/C++ 中比较常用的JSON 库主要有以下几个:

  • QJson
    QJson 是一个基于 Qt 的开发包用来将 JSON 数据解析成 QVariant 对象,JSON 的数组将被映射为QVariantList 实例,而其他对象映射为 QVariantMap 实例。
    网址:http://qjson.sourceforge.net/

关于 Qt 中对 JSON 的生成与解析,Qt5 以前的版本,可以使用 QJson 库,需要单独下载、编译,才能使用。到了 Qt5,提供了专门的 QJsonDocument 及其相关类来读和写 JSON 文档。

JSON 常用类

QJsonDocument

QJsonDocument 类用于读和写 JSON 文档。

一个 JSON 文档可以使用 QJsonDocument::fromJson() 从基于文本的表示转化为 QJsonDocument, toJson() 则可以反向转化为文本。解析器非常快且高效,并将 JSON 转换为 Qt 使用的二进制表示。

已解析文档的有效性,可以使用 !isNull() 进行查询。

如果要查询一个 JSON 文档是否包含一个数组或一个对象,使用 isArray() 和 isObject()。包含在文档中的数组或对象可以使用 array() 或 object() 检索,然后读取或操作。

也可以使用 fromBinaryData() 或 fromRawData() 从存储的二进制表示创建来 JSON 文档。

QJsonArray

QJsonArray 类封装了一个 JSON 数组。

JSON 数组是值的列表。列表可以被操作,通过从数组中插入和删除 QJsonValue 。

一个 QJsonArray 可以和一个 QVariantList 相互转换。可以使用 size() 来查询条目的数量,通过 insert() 在指定索引处插入值,removeAt() 来删除指定索引的值。

QJsonObject

QJsonObject 类封装了一个 JSON 对象。

一个 JSON 对象是一个“key/value 对”列表,key 是独一无二的字符串,value 由一个 QJsonValue 表示。

一个 QJsonObject 可以和一个 QVariantMap 相互转换。可以使用 size() 来查询“key/value 对”的数量,通过 insert() 插入“key/value 对”, remove() 删除指定的 key。

QJsonValue

QJsonValue 类封装了一个值。

JSON 中的值有 6 种基本数据类型:

  • bool(QJsonValue::Bool)

  • double(QJsonValue::Double)

  • string(QJsonValue::String)

  • array(QJsonValue::Array)

  • object(QJsonValue::Object)

  • null(QJsonValue::Null)

一个值可以由任何上述数据类型表示。此外,QJsonValue 有一个特殊的标记来表示未定义的值,可以使用 isUndefined() 查询。

值的类型可以通过 type() 或 isBool()、isString() 等访问函数查询。同样地,值可以通过 toBool()、toString() 等函数转化成相应的存储类型。

QJsonParseError

QJsonParseError 类用于在 JSON 解析中报告错误。

枚举 QJsonParseError::ParseError:

该枚举描述 JSON 文档在解析过程中所发生的错误类型。

常量

描述

QJsonParseError::NoError

0

未发生错误

QJsonParseError::UnterminatedObject

1

对象不正确地终止以右花括号结束

QJsonParseError::MissingNameSeparator

2

分隔不同项的逗号丢失

QJsonParseError::UnterminatedArray

3

数组不正确地终止以右中括号结束

QJsonParseError::MissingValueSeparator

4

对象中分割 key/value 的冒号丢失

QJsonParseError::IllegalValue

5

值是非法的

QJsonParseError::TerminationByNumber

6

在解析数字时,输入流结束

QJsonParseError::IllegalNumber

7

数字格式不正确

QJsonParseError::IllegalEscapeSequence

8

在输入时,发生一个非法转义序列

QJsonParseError::IllegalUTF8String

9

在输入时,发生一个非法 UTF8 序列

QJsonParseError::UnterminatedString

10

字符串不是以引号结束

QJsonParseError::MissingObject

11

一个对象是预期的,但是不能被发现

QJsonParseError::DeepNesting

12

对解析器来说,JSON 文档嵌套太深

QJsonParseError::DocumentTooLarge

13

对解析器来说,JSON 文档太大

QJsonParseError::GarbageAtEnd

14

解析的文档在末尾处包含额外的乱码

简单的 JSON 对象

构造一个简单的 JSON 对象:

{    "Cross Platform": true,    "From": 1991,    "Name": "Qt"}

生成比较简单,由于是一个对象,只需要用 QJsonObject 即可。

// 构建 JSON 对象
QJsonObject json;
json.insert("Name", "Qt");
json.insert("From", 1991);
json.insert("Cross Platform", true);

// 构建 JSON 文档
QJsonDocument document;
document.setObject(json);
QByteArray byteArray = document.toJson(QJsonDocument::Compact);
QString strJson(byteArray);

qDebug() << strJson;

解析如下:

QJsonParseError jsonError;

QJsonDocument doucment = QJsonDocument::fromJson(byteArray, &jsonError); // 转化为 JSON 文档

if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) { // 解析未发生错误

if (doucment.isObject()) { // JSON 文档为对象

QJsonObject object = doucment.object(); // 转化为对象

if (object.contains("Name")) { // 包含指定的 key

QJsonValue value = object.value("Name"); // 获取指定 key 对应的 value

if (value.isString()) { // 判断 value 是否为字符串

QString strName = value.toString(); // 将 value 转化为字符串

qDebug() << "Name : " << strName;

}

}

if (object.contains("From")) {

QJsonValue value = object.value("From");

if (value.isDouble()) {

int nFrom = value.toVariant().toInt();

qDebug() << "From : " << nFrom;

}

}

if (object.contains("Cross Platform")) {

QJsonValue value = object.value("Cross Platform");

if (value.isBool()) {

bool bCrossPlatform = value.toBool();

qDebug() << "CrossPlatform : " << bCrossPlatform;

}

}

}

}

注意:在转化为 QJsonDocument 后,首先需要根据 QJsonParseError 的值判定是否转化成功,然后在进行相应的转化解析。

简单的 JSON 数组

构造一个简单的 JSON 对象:

[    
"Qt",    
5.7,    
true
]

生成比较简单,由于是一个数组,只需要用 QJsonArray 即可。

// 构建 JSON 数组
QJsonArray json;
json.append("Qt");
json.append(5.7);
json.append(true);

// 构建 JSON 文档
QJsonDocument document;
document.setArray(json);
QByteArray byteArray = document.toJson(QJsonDocument::Compact);
QString strJson(byteArray);

qDebug() << strJson;

需要注意的是,和上面不同的是,这里使用的是 QJsonDocument 的 setArray() 函数,因为是数组嘛!

解析如下:

QJsonParseError jsonError;
QJsonDocument doucment = QJsonDocument::fromJson(byteArray, &jsonError);  // 转化为 JSON 文档
if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) { // 解析未发生错误
    if (doucment.isArray()) { // JSON 文档为数组
        QJsonArray array = doucment.array();  // 转化为数组
        int nSize = array.size();  // 获取数组大小
        for (int i = 0; i < nSize; ++i) {  // 遍历数组
            QJsonValue value = array.at(i);
            if (value.type() == QJsonValue::String) {
                QString strName = value.toString();
                qDebug() << strName;
            }
            if (value.type() == QJsonValue::Double) {
                double dVersion = value.toDouble();
                qDebug() << dVersion;
            }
            if (value.type() == QJsonValue::Bool) {
                bool bCrossPlatform  = value.toBool();
                qDebug() << bCrossPlatform;
            }
        }
    }
}

GitHub 加速计划 / cj / cJSON
10.45 K
3.16 K
下载
Ultralightweight JSON parser in ANSI C
最近提交(Master分支:3 个月前 )
424ce4ce This reverts commit 5b502cdbfb21fbe5f6cf9ffbd2b96e4281a741e6. Related to #860 5 个月前
32497300 - 6 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐