zoukankan      html  css  js  c++  java
  • QJsonDocument实现Qt下JSON文档读写

    博客地址已更改,文章数量较多不便批量修改,若想访问源文请到 coologic博客 查阅,网址:www.coologic.cn

    如本文记录地址为 techieliang.com/A/B/C/ 请改为 www.coologic.cn/A/B/C/ 即可查阅

    版权声明:若无来源注明,Techie亮博客文章均为原创。 转载请以链接形式标明本文标题和地址:
    本文标题:QJsonDocument实现Qt下JSON文档读写     本文地址:http://techieliang.com/2017/12/718/

    1. 介绍

    Qt提供了一系列类以供进行Json 文档的读写,分别为:

    QJsonDocumentJson文档、QJsonArray数组、QJsonObject对象、QJsonValue值、QJsonParseError错误。

    1.1. 错误分类

    ConstantValueDescription
    QJsonParseError::NoError 0 No error occurred
    QJsonParseError::UnterminatedObject 1 An object is not correctly terminated with a closing curly bracket
    QJsonParseError::MissingNameSeparator 2 A comma separating different items is missing
    QJsonParseError::UnterminatedArray 3 The array is not correctly terminated with a closing square bracket
    QJsonParseError::MissingValueSeparator 4 A colon separating keys from values inside objects is missing
    QJsonParseError::IllegalValue 5 The value is illegal
    QJsonParseError::TerminationByNumber 6 The input stream ended while parsing a number
    QJsonParseError::IllegalNumber 7 The number is not well formed
    QJsonParseError::IllegalEscapeSequence 8 An illegal escape sequence occurred in the input
    QJsonParseError::IllegalUTF8String 9 An illegal UTF8 sequence occurred in the input
    QJsonParseError::UnterminatedString 10 A string wasn’t terminated with a quote
    QJsonParseError::MissingObject 11 An object was expected but couldn’t be found
    QJsonParseError::DeepNesting 12 The JSON document is too deeply nested for the parser to parse it
    QJsonParseError::DocumentTooLarge 13 The JSON document is too large for the parser to parse it
    QJsonParseError::GarbageAtEnd 14 The parsed document contains additional garbage characters at the end

    1.2. Json内容读写

    QJsonDocument::toJson可以生成json文档,具有可选参数,可以生成紧凑结构和缩进结构:

    ConstantValueDescription
    QJsonDocument::Indented 0 Defines human readable output as follows:
    {
        "Array": [
            true,
            999,
            "string"
        ],
        "Key": "Value",
        "null": null
    }
    QJsonDocument::Compact 1 Defines a compact output as follows:
    {"Array":[true,999,"string"],"Key":"Value","null":null}

    除此以外还可以用toBinaryDatatoVariant用于结果输出

    QJsonDocument除了使用构造函数创建以外,还支持静态函数创建,主要用于读取已有文件的内容:

    1. QJsonDocument fromBinaryData(const QByteArray &data, DataValidation validation = Validate)
    2. QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR)
    3. QJsonDocument fromRawData(const char *data, int size, DataValidation validation = Validate)
    4. QJsonDocument fromVariant(const QVariant &variant)

    QJsonDocument并不会直接操作文件,需要自行利用QFile进行readAll或者Write

    fromRawData/fromBinaryData并不会返回QJsonParseError错误而是直接返回DataValidation枚举类型,表明读取的数据是否有效

    ConstantValueDescription
    QJsonDocument::Validate 0 Validate the data before using it. This is the default.
    QJsonDocument::BypassValidation 1 Bypasses data validation. Only use if you received the data from a trusted place and know it’s valid, as using of invalid data can crash the application.

    1.3. 数据类型

    QJsonValue用于存储所有值,可以用type判断其类型,含以下类型

    ConstantValueDescription
    QJsonValue::Null 0x0 A Null value
    QJsonValue::Bool 0x1 A boolean value. Use toBool() to convert to a bool.
    QJsonValue::Double 0x2 A double. Use toDouble() to convert to a double.
    QJsonValue::String 0x3 A string. Use toString() to convert to a QString.
    QJsonValue::Array 0x4 An array. Use toArray() to convert to a QJsonArray.
    QJsonValue::Object 0x5 An object. Use toObject() to convert to a QJsonObject.
    QJsonValue::Undefined 0x80 The value is undefined. This is usually returned as an error condition, when trying to read an out of bounds value in an array or a non existent key in an object.

    也可以通过isXXXX用于判断,并通过toXXXX转换为对应类型

    2. 读写操作

    2.1. json范例

    1. {
    2. "Array": [
    3. true,
    4. 999,
    5. "string"
    6. ],
    7. "Key": "Value",
    8. "null": null
    9. }

    3. 创建

    1. #include <QCoreApplication>
    2. #include <QJsonDocument>//json文档
    3. #include <QJsonArray>//json数组
    4. #include <QJsonObject>//json对象
    5. #include <QJsonValue>//json值
    6. #include <QJsonParseError>//错误处理
    7. #include <QDebug>
    8. int main(int argc, char *argv[]) {
    9. QCoreApplication a(argc, argv);
    10. QJsonDocument json;
    11. QJsonArray array;
    12. array.append(true);
    13. array.append(999);
    14. array.append("string");
    15. QJsonObject object;
    16. object.insert("Array",array);
    17. object.insert("Key","Value");
    18. //null用空的QJsonValue即可
    19. object.insert("null",QJsonValue());
    20. //最外层是大括号所以是object
    21. json.setObject(object);
    22. qDebug()<<json.toJson(QJsonDocument::Compact);
    23. return 0;
    24. }

    此时使用QJsonDocument::Compact方式写出,其结果为:

    “{”Array”:[true,999,”string”],”Key”:”Value”,”null”:null}”

    QDebug会将 直接输出成 而不会换行

    4. 解析

    1. #include <QCoreApplication>
    2. #include <QJsonDocument>//json文档
    3. #include <QJsonArray>//json数组
    4. #include <QJsonObject>//json对象
    5. #include <QJsonValue>//json值
    6. #include <QJsonParseError>//错误处理
    7. #include <QDebug>
    8. int main(int argc, char *argv[]) {
    9. QCoreApplication a(argc, argv);
    10. QJsonDocument json;
    11. QJsonArray array;
    12. array.append(true);
    13. array.append(999);
    14. array.append("string");
    15. QJsonObject object;
    16. object.insert("Array",array);
    17. object.insert("Key","Value");
    18. //null用空的QJsonValue即可
    19. object.insert("null",QJsonValue());
    20. //最外层是大括号所以是object
    21. json.setObject(object);
    22. auto json_text = json.toJson(QJsonDocument::Compact);
    23. auto json_binary = json.toBinaryData();
    24. QJsonDocument read1 = QJsonDocument::
    25. fromJson(json_text);
    26. QJsonDocument read2 = QJsonDocument::
    27. fromBinaryData(json_binary);
    28. //验证两个是一样的
    29. if(QString(read1.toBinaryData()) ==
    30. QString(read2.toBinaryData()))
    31. qDebug()<<"same";
    32. //用于判断是否为空,对QJsonXXX对象均支持
    33. if(!read1.isEmpty())
    34. qDebug()<<"empty";
    35. //下面开始解析代码
    36. if(read1.isObject() ) {
    37. auto read_object = read1.object();
    38. if(!read_object.isEmpty()) {
    39. qDebug()<<read_object.value("Key").toString();
    40. qDebug()<<read_object.value("null").isNull();
    41. QJsonValue value = read_object.value("Array");
    42. qDebug()<<value.type()<<value;
    43. if(value.isArray()) {
    44. auto read_array = value.toArray();
    45. for(auto one_of_array : read_array)
    46. qDebug()<<one_of_array;
    47. //此处建议判断好具体类型,因为array里面也可能有object
    48. }
    49. }
    50. }
    51. return 0;
    52. }

    结果

    1. same
    2. empty
    3. "Value"
    4. true
    5. 4 QJsonValue(array, QJsonArray([true,999,"string"]))
    6. QJsonValue(bool, true)
    7. QJsonValue(double, 999)
    8. QJsonValue(string, "string")

    根据正常的结构进行判断即可,对于array需要进行遍历,支持C++的for(:)方式遍历

    fromJson、fromBinaryData、fromRawData、fromVariant这几个静态函数都不会直接返回成功与否,而是在参数中实现解析结果判断,正式使用时务必进行判断,避免后续代码均出错

    5. 其他

    1. 对于每一步建议明确判断QJsonValut的type如果type错误,会输出为””,比如int类型用toString不会自动转换,而是直接写出””
    2. 相比于Qt使用core模块的xml读写,json操作很简单,不需要逐行的读取操作使用readNext,获取内容的顺序与文本顺序可以不一致,xml使用请见文章:QXmlStreamReader/QXmlStreamWriter实现Qt下xml文件读写
    3. 上面介绍的例子最外层为object,也支持最外层为array,使用setArray即可,最外层只能为一种,不能不断的add
    4. QJsonDocument主要负责的是数据文本格式或者说是表现方式的转换,其余类负责内容
    5. QJsonArray可以用size获取数组的大小,后续操作感觉类似于QList<QVariant> ,也具有迭代器
    6. QJsonParseError使用方式自行查看,主要是在解析时出现,但均不会作为返回值直接返回,在QJsonDocument::fromJson处使用,其余几个静态fromXXX函数直接返回枚举类型,此类操作均不可保证绝对正确,故应当做判断避免后续连锁错误。
    转载请以链接形式标明本文标题和地址:Techie亮博客 » QJsonDocument实现Qt下JSON文档读写
  • 相关阅读:
    (BFS 二叉树) leetcode 515. Find Largest Value in Each Tree Row
    (二叉树 BFS) leetcode513. Find Bottom Left Tree Value
    (二叉树 BFS DFS) leetcode 104. Maximum Depth of Binary Tree
    (二叉树 BFS DFS) leetcode 111. Minimum Depth of Binary Tree
    (BFS) leetcode 690. Employee Importance
    (BFS/DFS) leetcode 200. Number of Islands
    (最长回文子串 线性DP) 51nod 1088 最长回文子串
    (链表 importance) leetcode 2. Add Two Numbers
    (链表 set) leetcode 817. Linked List Components
    (链表 双指针) leetcode 142. Linked List Cycle II
  • 原文地址:https://www.cnblogs.com/techiel/p/8053238.html
Copyright © 2011-2022 走看看