QT中JSON解析

一、简介

JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。有关更多解释,可以去JSON官网查看。

二、JSON类介绍

在Qt库中,为JSON的相关操作提供了完整的类支持,包括QJsonValue,QJsonObject,QJsonArray,QJsonDocument和QJsonParseError。

QJsonValue类表示json格式中的一个值;
QJsonObject表示一个json对象;
QJsonArray顾名思义表示一个json数组;
QJsonDocument主要用来读写json文档;
QJsonParseError是用来表示json解析过程中出现的错误的方便类。

三、JSON类使用

QJsonValue

JSON是一种存储结构化数据的格式。 它具有6种基本数据类型:

bool QJsonValue::Bool
double QJsonValue::Double
string QJsonValue::String
array QJsonValue::Array
object QJsonValue::Object
null QJsonValue::Null

一个QJsonValue可以表示上面任何一种数据类型。此外,QJsonValue还有一个特殊的标志用来表示未定义的值。可以使用isUndefined()函数来进行判断。而一个QJsonValue中存储的类型可以通过type()或isBool(),isString()之类的函数进行查询。同样,QJsonValue中存储的值可以通过toBool(),toString()等函数转换到具体的类型。

QJsonValue中存储的值在内部是强类型的,并且和QVariant相反,它不会尝试进行任何的隐式类型转换。这意味着将QJsonValue转换成一个不是它存储的类型,将返回一个该类型的模型构造函数返回的值。

其实,说到QJsonValue,还有另一个类要说,QJsonValueRef,该类是一个对于QJsonArray和QJsonObject来说的一个帮助类。当你获得一个QJsonValueRef类的对象后,你可以把它当做一个QJsonValue对象的应用来使用。如果你向他赋值,该值会实际作用到底层的QJsonArray或者QJsonObject对象中的元素上。而要想使用该类,可以使用一下的两个方法:

QJsonArray::operator[](int i)
QJsonObject::operator[](const QString& key)const;

下面来看一下QJsonValue的构造函数:

QJsonValue(Type type = Null)

QJsonValue(bool b)

QJsonValue(double n)

QJsonValue(int n)

QJsonValue(qint64 n)

QJsonValue(const QString &s)

QJsonValue(QLatin1String s)

QJsonValue(const char *s)

QJsonValue(const QJsonArray &a)

QJsonValue(const QJsonObject &o)

QJsonValue(const QJsonValue &other)

可以看到,该类主要是对基本类型的一个包装。

QJsonObject

QJsonObject类封装了一个json对象。一个json对象是一个键值对的列表,其中key是唯一的字符串,而值就是一个我们上面讲到的QJsonValue。一个QJsonObject的对象可以转换到QVariantMap,要可以由QVariantMap转换得到。

我们可以使用size()函数来查询一个QJsonObject中存储的键值对的个数;使用insert()和remove()来插入或从中删除键值对;还可以使用标准的C++迭代器来遍历它。

QJsonObject类是一个隐式共享类。

其构造函数如下:

QJsonObject()

QJsonObject(std::initializer_list<QPair<QString, QJsonValue> > args)

QJsonObject(const QJsonObject &other)

我们可以使用初始化列表来快速的构建一个QJsonObject对象。如下:

QJsonObject object

{

{"property1", 1},

{"property2", 2}

};

如此之外,比较常用的就是insert()函数了:

iterator QJsonObject::insert(const QString &key, const QJsonValue &value)
一般,我们可以先定义一个空的QJsonObject对象,然后使用该函数向其中插入需要的键值对。如果新插入的key已存在,那么会进行替换。

#include <QCoreApplication>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonParseError>
#include <QDebug>
#include <QFile>


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QJsonObject obj1;

    obj1.insert("name",QJsonValue("zhangsan"));
    obj1.insert("age",QJsonValue("22"));
    QJsonObject obj1_addr;
    obj1_addr.insert("city",QJsonValue("guangzhou"));
    obj1_addr.insert("province",QJsonValue("guangdong"));
    obj1.insert("addr",QJsonValue(obj1_addr));

    qDebug()<<obj1;
}

QJsonArray

顾名思义,QJsonArray封装了一个JSON数组。一个JSON数组是一个值的列表。我们可以向这个列表中插入或删除QJsonValue。

同时,我们可以把一个QVariantList转换成一个QJsonArray。也可以使用标准C++迭代器对它进行遍历。

其构造函数如下:

QJsonArray()

QJsonArray(std::initializer_list<QJsonValue> args)

QJsonArray(const QJsonArray &other)

我们也可以像上面那样,使用一个初始化列表来构建一个QJsonArray对象:

QJsonArray array = { 1, 2.2, QString() };

在此我们只使用了单个的值,没有使用键值对。其实,这样的json对象,一般我们就称为数组。

和QJsonObject一样,我们一般也是通过它的insert()函数来生成我们需要的json数组:

void insert(int i, const QJsonValue &value)

iterator insert(iterator before, const QJsonValue &value)

下面,我们继续上面的例子,来生成一个表示人物信息的列表。代码如下:

#include <QCoreApplication>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonParseError>
#include <QDebug>
#include <QFile>


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

#if 1
    QJsonObject obj1;

    obj1.insert("name",QJsonValue("zhangsan"));
    obj1.insert("age",QJsonValue("22"));
    QJsonObject obj1_addr;
    obj1_addr.insert("city",QJsonValue("guangzhou"));
    obj1_addr.insert("province",QJsonValue("guangdong"));
    obj1.insert("addr",QJsonValue(obj1_addr));

    qDebug()<<obj1;

    QJsonObject obj2;

    obj2.insert("name",QJsonValue("lisi"));
    obj2.insert("age",QJsonValue("25"));
    QJsonObject obj2_addr;
    obj2_addr.insert("city",QJsonValue("zhanjiang"));
    obj2_addr.insert("province",QJsonValue("guangdong"));
    obj2.insert("addr",QJsonValue(obj2_addr));

    qDebug()<<obj2;

    QJsonArray objarray;

    objarray.insert(0,obj1);
    objarray.insert(0,obj2);

    qDebug()<<"********************";
    qDebug()<<objarray;
}

运行结果如下:
在这里插入图片描述

QJsonDocument

QJsonDocument类提供了读写JSON文档的方法。QJsonDocument类包装了一个完整的JSON 文档,我们可以以utf-8编码的文本格式和Qt自己的二进制格式来操作该文档。一个JSON文档可以使用QJsonDocument::fromJson()函数转换json文本字符串来得到。而toJson()可以将其转换成文本。这个解析器是非常快速和高效的,Qt也是使用它来将JSON对象转换成其二进制表示的。解析得到的文档可以使用isNull()来判断是否有效。还可以使用isArray()和isObject()函数来判断该文档所包含的是否是数据或json对象。如果是,可以使用array()或object()函数还获得其中的对象或数组。

其构造函数如下:

QJsonDocument()

QJsonDocument(const QJsonObject &object)

QJsonDocument(const QJsonArray &array)

QJsonDocument(const QJsonDocument &other)

除了构造函数外,该类还提供了两个转换函数,可以将json文档序列化为二进制对象,然后我们就可以将该对象存储到文件中,或发送到网络上。

QByteArray toBinaryData() const

QByteArray toJson(JsonFormat format = Indented) const

下面,我们就使用该类将我们上面生成的json数组写入到文件中:

#include <QCoreApplication>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonParseError>
#include <QDebug>
#include <QFile>


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

#if 1
    QJsonObject obj1;

    obj1.insert("name",QJsonValue("zhangsan"));
    obj1.insert("age",QJsonValue("22"));
    QJsonObject obj1_addr;
    obj1_addr.insert("city",QJsonValue("guangzhou"));
    obj1_addr.insert("province",QJsonValue("guangdong"));
    obj1.insert("addr",QJsonValue(obj1_addr));

    qDebug()<<obj1;

    QJsonObject obj2;

    obj2.insert("name",QJsonValue("lisi"));
    obj2.insert("age",QJsonValue("25"));
    QJsonObject obj2_addr;
    obj2_addr.insert("city",QJsonValue("zhanjiang"));
    obj2_addr.insert("province",QJsonValue("guangdong"));
    obj2.insert("addr",QJsonValue(obj2_addr));

    qDebug()<<obj2;

    QJsonArray objarray;

    objarray.insert(0,obj1);
    objarray.insert(0,obj2);

    qDebug()<<"********************";
    qDebug()<<objarray;



    QJsonDocument doc(objarray);
    QByteArray text =  doc.toJson();

    QFile file("result.json");
    if(!file.open(QIODevice::WriteOnly)){
        qDebug()<<"open json error";
        return -1;
    }

    file.write(text.data());


    file.close();
}

我们先使用QJsonArray构建出一个QJsonDocument对象,然后调用其toJson()方法,将该json文档转换成一个字节数组。注意,toJson()函数会接受一个格式化参数:

QByteArray QJsonDocument::toJson(JsonFormat format = Indented) const

其中,format主要有两种格式,一种是人们可读的格式,一种是紧凑的格式。分别描述如下表:
在这里插入图片描述
toJson()函数默认使用Indented,一缩进的形式生成人们可读的json文件。

打开生成result.json文件,如下:
在这里插入图片描述
当然,除了将json对象写入到文件中,QJsonDocument还提供了几个静态函数,将从文件中读取出的原始数据或json字符串转换成一个QJsonDocument对象。函数声明信息如下:

QJsonDocument fromBinaryData(const QByteArray &data, DataValidation validation = Validate)

QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR)

QJsonDocument fromRawData(const char *data, int size, DataValidation validation = Validate)

QJsonDocument fromVariant(const QVariant &variant)

下面,我们就使用这些函数,将我们写入到文件中的json对象再读出来,并生成一个QJsonDocument对象。

#include <QCoreApplication>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonParseError>
#include <QDebug>
#include <QFile>


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QFile file("result.json");

    if(!file.open(QIODevice::ReadOnly)){
        qDebug()<<"read json error";
        return -1;
    }
    QJsonParseError failresult;
    QJsonDocument doc = QJsonDocument::fromJson(file.readAll(),&failresult);

    if(!doc.isNull() && (failresult.error == QJsonParseError::NoError))
    {
        qDebug()<<"doc:"<<doc;

        QJsonObject rootobj = doc.object();
        //解析数据
        QJsonArray rootarray= doc.array();

        for(int i=0; i<rootarray.size(); i++){
            QJsonValue tempval =  rootarray.at(i);
            if(tempval.isObject()){
                QJsonObject tempobj = tempval.toObject();
                if(!tempobj.isEmpty()){
                    qDebug()<<"************";
                    qDebug()<<"name:"<<tempobj.value("name").toString();
                    qDebug()<<"age:"<<tempobj.value("age").toString();

                    if(tempobj.value("addr").isObject()){
                        QJsonObject addrobj = tempobj.value("addr").toObject();
                        qDebug()<<"addr city:"<<addrobj.value("city").toString();
                        qDebug()<<"addr province:"<<addrobj.value("province").toString();
                    }
                }
            }
        }

    }
    else
        qDebug()<<failresult.errorString();


    file.close();

    return a.exec();
}

运行结果如下:

在这里插入图片描述
以上例子是通过QJsonDocument 类读写Json文档,然后利用QJsonObject 和QJsonValue 类 将读取出来的Json数据进行解析。

  • 4
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt,可以使用QJsonDocument和QJsonObject类来解析和处理JSON数据。 首先,需要将JSON数据转换为QJsonDocument对象。可以使用QJsonDocument::fromJson()方法将JSON字符串或字节数组转换为QJsonDocument对象。例如: ```cpp QString jsonString = "{\"name\":\"John\",\"age\":30}"; QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8()); // 或者 QByteArray jsonData = "{\"name\":\"John\",\"age\":30}"; QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData); ``` 然后,可以通过调用`jsonDoc.object()`方法获取QJsonObject对象,以便访问和处理JSON数据的键值对。例如: ```cpp QJsonObject jsonObj = jsonDoc.object(); QString name = jsonObj["name"].toString(); int age = jsonObj["age"].toInt(); ``` 对于嵌套的JSON结构,可以通过递归方式进行解析。例如,如果JSON数据包含一个嵌套的数组: ```cpp QString jsonArrayString = "{\"people\":[{\"name\":\"John\",\"age\":30},{\"name\":\"Alice\",\"age\":25}]}"; QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonArrayString.toUtf8()); QJsonObject jsonObj = jsonDoc.object(); QJsonArray peopleArray = jsonObj["people"].toArray(); foreach (const QJsonValue& value, peopleArray) { QJsonObject personObj = value.toObject(); QString name = personObj["name"].toString(); int age = personObj["age"].toInt(); // 处理每个人的数据 } ``` 以上是一个简单的JSON解析示例,根据实际情况,可能需要根据JSON数据的结构进行更复杂的处理和解析

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值