1.通过类似window路径的方式访问json

#ifndef JSONPATH_H
#define JSONPATH_H

#include <QObject>
#include <QJsonDocument>
#include <QVariant>
#include <QJsonValue>
class JsonPathReader : public QObject {
    Q_OBJECT

public:
    JsonPathReader(const QByteArray &byte, QObject *parent = nullptr);

    QJsonValue jsonValue(const char *cformat, ...);
    static QJsonValue JsonValue(const QJsonValue &var, const char *cformat, ...);
    QVariant value(const char *cformat, ...);
    static QVariant Value(const QJsonValue &var, const char *cformat, ...);
    int arrayCount(const char *cformat, ...);

    QJsonParseError::ParseError errorType();
    QString errString();

    static QStringList path2List(const QString &path);
    static QJsonValue _jsonValue(QJsonValue var, const QString &path);

private:
    QJsonValue _jsonValue(const QString &path);
    int _arrayCount(const QString &path);

private:
    QJsonValue json;
    QJsonParseError err;
};

class JsonPathWriter : public QObject {
    Q_OBJECT

public:
    JsonPathWriter(QObject *parent = nullptr);
    void parse(const QByteArray &byte);

    bool setValue(const QString &path, const QVariant &var);
    bool append(const QString &path, const QMap<QString, QVariant> &obj, bool doClear = false);
    QByteArray toJson();
private:
    QVariant *mapValuePtr(const QString &path);

private:
    QVariant json;
};

#endif // JSONPATH_H

 

#include "jsonpath.h"
#include <QVariant>
#include <QJsonArray>
#include <QJsonObject>
#include <QtWidgets>


#define STR_SPRINTF(path) \
    va_list ap; \
    va_start(ap, cformat); \
    path = QString::vasprintf(cformat, ap); \


JsonPathReader::JsonPathReader(const QByteArray &byte, QObject *parent)
    : QObject(parent)
{
    QJsonDocument doc = QJsonDocument::fromJson(byte, &err);
    if(doc.isArray()) {
        json = doc.array();
    } else if(doc.isObject()) {
        json = doc.object();
    }
}

QJsonValue JsonPathReader::jsonValue(const char *cformat, ...)
{
    QString path;STR_SPRINTF(path);
    return _jsonValue(path);
}

QJsonValue JsonPathReader::JsonValue(const QJsonValue &var, const char *cformat, ...)
{
    QString path;STR_SPRINTF(path);
    return _jsonValue(var, path);
}

QVariant JsonPathReader::value(const char *cformat, ...)
{
    QString path;STR_SPRINTF(path);
    return _jsonValue(path).toVariant();
}

QVariant JsonPathReader::Value(const QJsonValue &var, const char *cformat, ...)
{
    QString path;STR_SPRINTF(path);
    return _jsonValue(var, path).toVariant();
}

int JsonPathReader::arrayCount(const char *cformat, ...)
{
    QString path;STR_SPRINTF(path);
    return _arrayCount(path);
}

QJsonParseError::ParseError JsonPathReader::errorType()
{
    return err.error;
}

QString JsonPathReader::errString()
{
    return err.errorString();
}

QStringList JsonPathReader::path2List(const QString &path)
{
    QStringList list;
    for(int k = 0; k < path.count(); k ++) {
        if(path.mid(k, 1) == "[") {
            list << "[";
        } else if(path.mid(k, 1) == "/"){
            list << "{";
        } else if(k == 0) {
            list << "{" + path.mid(0, 1);
        } else {
            list.last() += path.mid(k, 1);
        }
    }
    return list;
}

QJsonValue JsonPathReader::_jsonValue(const QString &path)
{
    if(err.error != QJsonParseError::NoError) {
        return QJsonValue();
    }
    return _jsonValue(json, path);
}

QJsonValue JsonPathReader::_jsonValue(QJsonValue var, const QString &path)
{
    QStringList list = path2List(path);
    //
    for(int k = 0; k < list.count(); k ++) {
        QString type = list[k].mid(0, 1);
        QString name = list[k].mid(1);
        if(type == "[") {
            var = var.toArray().at(name.toInt());
        } else if(type == "{") {
            var = var.toObject().value(name);
        }
    }
    return var;
}

int JsonPathReader::_arrayCount(const QString &path)
{
    QJsonValue var = _jsonValue(path);
    if(var.isArray()) {
        return var.toArray().count();
    }
    return 0;
}

JsonPathWriter::JsonPathWriter(QObject *parent)
{
}

void JsonPathWriter::parse(const QByteArray &byte)
{
    QJsonDocument doc = QJsonDocument::fromJson(byte);
    json = doc.toVariant();
}


bool JsonPathWriter::setValue(const QString &path, const QVariant &var)
{
    QStringList list = JsonPathReader::path2List(path);
    QVariant *v = mapValuePtr(path);
    if(v == nullptr)
        return false;
    *v = var;
    return true;
}

bool JsonPathWriter::append(const QString &path, const QMap<QString, QVariant> &obj, bool doClear)
{
    QStringList list = JsonPathReader::path2List(path);
    QVariant *v = mapValuePtr(path);
    if(v == nullptr)
        return false;
    if(QString("QVariantList") != v->typeName())
        return false;
    QVariantList *arr= (QVariantList *)v;
    if(doClear) {
        arr->clear();
    }
    arr->append(obj);
    return true;
}

QByteArray JsonPathWriter::toJson()
{
    QJsonDocument doc;
    QJsonValue var = QJsonValue::fromVariant(json);
    if(var.isObject()) {
        doc.setObject(var.toObject());
    } else if(var.isArray()) {
        doc.setArray(var.toArray());
    }
    return doc.toJson();
}


QVariant *JsonPathWriter::mapValuePtr(const QString &path)
{
    QStringList list = JsonPathReader::path2List(path);
    //
    QMap<QString, QVariant> *obj;
    QVariantList *array;
    QVariant *var = &json;
    for(int k = 0; k < list.count(); k ++) {
        if(var == nullptr)
            break;

        QString type = list[k].mid(0, 1);
        QString name = list[k].mid(1);
        if(type == "[") {
            array = (QVariantList *)var;
            if(0 <= name.toInt() && name.toInt() < array->count())
                var = &(*array)[name.toInt()];
            else
                var = nullptr;
        } else if(type == "{") {
            obj = (QMap<QString, QVariant> *)var;
            if(obj->contains(name))
                var = &(*obj)[name];
            else
                var = nullptr;
        }
    }
    return var;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值