Qt读写Json操作

一、Qt中对Json操作封装的类 1. QJsonArray 2. QJsonDocument 3. […]

2018年6月11日

一、Qt中对Json操作封装的类

1. QJsonArray

2. QJsonDocument

3. QJsonObject

4. QJsonParseError

5. QJsonValue

二、各类详细说明

1. QJsonArray

QJsonArray 类封装了一个 JSON 数组。

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

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

QJsonArray是一个隐式共享类,只要它没有被修改,就会与创建它的文档共享数据。
QJsonArray对象和基于文本的JSON可以通过QJsonDocument进行相互转换。

2. QJsonDocument

QJsonDocument类提供了读写JSON文档的方法。

QJsonDocument是一个封装了完整JSON文档的类,可以从基于UTF-8编码的文本或者Qt的二进制格式读写此文档。

可以使用QJsonDocument :: fromJson()将JSON文档从其基于文本的表示转换为QJsonDocument。
可以使用QJsonDocument :: toJson()将其转换回文本。
解析器非常快速有效,并将JSON转换为Qt使用的二进制表示。

可以使用!isNull()查询已解析文档的有效性
可以使用isArray()和isObject()查询文档是否包含数组或对象。
可以使用array()或object()检索文档中包含的数组或对象,然后进行读取或操作。
还可以使用fromBinaryData()或fromRawData()从存储的二进制表示创建文档。

3. QJsonObject

QJsonObject 类封装了一个 JSON 对象。

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

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

QJsonObject是一个隐式共享类,只要它没有被修改,就会与创建它的文档共享数据。
QJsonObject对象和基于文本的JSON可以通过QJsonDocument进行相互转换。

4. QJsonParseError

QJsonParseError类用于在JSON解析期间报告错误。
枚举QJsonParseError :: ParseError
该枚举描述了在解析JSON文档期间发生的错误类型。

Constant Value Description
QJsonParseError::NoError 0 没有发生错误
QJsonParseError::UnterminatedObject 1 对象没有正确地用大括号括起来
QJsonParseError::MissingNameSeparator 2 缺少分隔不同项目的逗号
QJsonParseError::UnterminatedArray 3 数组未正确用方括号括起来
QJsonParseError::MissingValueSeparator 4 缺少将键与对象内的值分隔开的冒号
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 解析的文档末尾包含其他垃圾字符

5. 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() 等函数转化成相应的存储类型。

与QVariant相反,不会尝试进行任何隐式类型转换。 这意味着转换为未存储在值中的类型将返回默认的构造返回值。

三、实例

Json实例文本如下:

    {
    "Data": [                                       //QJsonObject rootObject                                    
        {
            "myApple": {                            //QJsonObject branchObject
                "color": red,                       //QJsonObject leafObject
                "weight": 2                         //QJsonObject leafObject
            }
        },
        {
            "myWatermelon": {
                "color": green,
                "weight": 5.2
            }
        },
        {
            "myHeight": {                           //QJsonObject branchObject
                "value": 180                        //QJsonObject leafObject
            }
        },
        {
            "myWeight": {
                "value": 60
            }
        }
    ]
}

写Json文件

//创建并写入Json文件
void JsonObj::createJsonFile(const QString& fileName)
{
    QJsonArray jsonArray;
    QJsonObject rootObject;
    QJsonObject branchObject;
    QJsonObject leafObject;

    leafObject.insert("color", "red"); //先写叶子结点
    leafObject.insert("weight", 2);
    branchObject.insert("myApple", leafObject); //父结点插入叶子结点
    jsonArray.append(branchObject); //最后把父结点加入到Json数组中
    clearJsonObject(leafObject); //清空数据
    clearJsonObject(branchObject);

    leafObject.insert("color", "green");
    leafObject.insert("weight", 5.2);
    branchObject.insert("myWatermelon", leafObject);
    jsonArray.append(branchObject);
    clearJsonObject(leafObject);
    clearJsonObject(branchObject);

    leafObject.insert("value", 180);
    branchObject.insert("myHeight", leafObject);
    jsonArray.append(branchObject);
    clearJsonObject(leafObject);
    clearJsonObject(branchObject);

    leafObject.insert("value", 60);
    branchObject.insert("myWeight", leafObject);
    jsonArray.append(branchObject);
    clearJsonObject(leafObject);
    clearJsonObject(branchObject);

    rootObject.insert("Data", jsonArray); //最后把Json数组插入到根结点

    //初始化JsonDocument
    QJsonDocument jsonDocument;
    jsonDocument.setObject(rootObject);

    //JsonDocument转为ByteArray
    QByteArray byteArray = jsonDocument.toJson(QJsonDocument::Indented);

    //写入文件,fileNama为Json文件路径 :./Data.json
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qDebug() << QString("fail to open the file: %1, %2, %3").arg(__FILE__).arg(__LINE__).arg(__FUNCTION__);
        return;
    }
    QTextStream out(&file);
    out << byteArray;

    file.close();

    qDebug() << byteArray;
}

//清空数据
void JsonObj::clearJsonObject(QJsonObject& object)
{
    QStringList strList = object.keys();

    for (int i = 0; i < strList.size(); ++i) {
        object.remove(strList.at(i));
    }
}

读Json文件(解析Json文件)

实例Json文本如下:

{
  "Data": [
    {
      "myApple": {
        "color": "red",
        "weight": 2
      }
    },
    {
      "myWatermelon": {
        "color": "green",
        "weight": 5.2
      }
    },
    {
      "myHeight": {
        "value": 180
      }
    },
    {
      "myWeight": {
        "value": 60
      }
    }
  ],
  "data2": [
    {
      "myKeys": {
        "color": "key",
        "weight": 5
      }
    }
  ]
}

代码如下:

void JsonObj::parseJsonFile(const QString& fileName)
{
    //打开Json文件并用QByteArray读取全部内容
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << QString("fail to open the file: %1, %2, %3").arg(__FILE__).arg(__LINE__).arg(__FUNCTION__);
        return;
    }
    QByteArray array = file.readAll();
    file.close();

    //读取的全部内容转为QJsonDocument,如果报错则输出错误信息
    QJsonParseError jsonParseError;
    QJsonDocument jsonDocument(QJsonDocument::fromJson(array, &jsonParseError));
    if (QJsonParseError::NoError != jsonParseError.error) {
        qDebug() << QString("JsonParseError: %1").arg(jsonParseError.errorString());
        return;
    }
    //QJsonDocument转为QJsonObject
    QJsonObject rootObject = jsonDocument.object();

    //获取根结点
    QStringList keys = rootObject.keys();
    for (int i = 0; i < keys.size(); i++) {
        qDebug() << "key" << i << " is:" << keys.at(i);
    }

    //根据获取到的根结点继续获取二级结点
    for (int i = 0; i < keys.size(); i++) {
        if (rootObject.contains(keys.at(i)) && rootObject[keys.at(i)].isArray()) {
            QJsonArray subArray = rootObject.value(keys.at(i)).toArray();
            for (int i = 0; i < subArray.size(); i++) {
                if (subArray[i].isObject()) {
                    QStringList subKeys = subArray[i].toObject().keys();
                    for (int m = 0; m < subKeys.size(); m++) {
                        qDebug() << "Subkey is:" << subKeys.at(m);

                        //根据获取到的二级结点继续获取三级结点
                        QJsonObject subObj = subArray[i].toObject()[subKeys.at(m)].toObject();
                        QStringList subObjKeys = subObj.keys();
                        if (subArray[i].toObject().contains(subKeys.at(m)) && subArray[i].toObject()[subKeys.at(m)].isObject()) {

                            if (subObj.contains("color") && subObj["color"].isString()) {
                                qDebug() << "color is:" << subObj["color"].toString();
                            }
                            if (subObj.contains("weight") && subObj["weight"].isDouble()) {
                                qDebug() << "weight is:" << subObj["weight"].toDouble();
                            }
                            if (subObj.contains("value") && subObj["value"].isDouble()) {
                                qDebug() << "value is:" << subObj["value"].toDouble();
                            }
                        }
                    }
                }
            }
        }
    }
}

输出内容如下:

key 0  is: "Data"
key 1  is: "data2"
Subkey is: "myApple"
color is: "red"
weight is: 2
Subkey is: "myWatermelon"
color is: "green"
weight is: 5.2
Subkey is: "myHeight"
value is: 180
Subkey is: "myWeight"
value is: 60
Subkey is: "myKeys"
color is: "key"
weight is: 5
打赏 0

共有 0 条评论