当前位置:网站首页>1.通过类似window路径的方式访问json
1.通过类似window路径的方式访问json
2022-07-22 09:12:00 【氺月洞天】
#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;
}
边栏推荐
- 总结20220210
- Fortress machine, DMZ area
- No input file specified solution
- [FatFs] FAT32 file system protocol summary (Theory + Practice)
- uniapp 微信小程序地图,在高德app、腾讯app、百度app、苹果地图app 中打开
- [Nordic] nrf52810 OTA upgrade (III) – DFU theoretical analysis
- 05. Law of Demeter LOD
- 微信小程序本地访问本地TP5的路由接口正常,为何在手机上扫码预览获取不到数据?
- Interview experience of Android Internet manufacturers
- Method of getting node binding data data index by applet
猜你喜欢
随机推荐
Fortress machine, DMZ area
位与:一个数&1的结果
【Audio】基于STM32 I2S移植WM8978 Audio Codec驱动
【TOOLS】TortoiseSVN如何设置比较工具为Beyond Compare 4
24 条 SaaS 思考
[SDIO] sd2.0 protocol analysis summary (I) -- Introduction to SD card basic probability
PHP实现删除一维数组中某一个值
no input file specified 解决方案
07. Composite/aggregate Reuse Principle (carp)
charm zaza functional test (by quqi99)
sshfs + autofs + sshpass (by quqi99)
01. Open closed principle
win10sp1升到最新版本;QT5.9.6静态编译(network有效)
Go 并发模式:管道和取消
[tools] how to set the comparison tool for TortoiseSVN to beyond compare 4
Summary 20220120
ecshop配置微信支付,微信开发者工具微信支付时弹窗提示“未绑定网页开发者”问题
AMH multiple MySQL versions coexist?
协议与端口
Go 语言学习:Go 语言之旅(五)