Qt JSON数据解析和存储详解

本文详细介绍了JSON数据格式及其在Qt中的解析和存储方法,包括JSON的结构、解析常用方法,并通过实例展示了如何处理复杂的JSON数据。
摘要由CSDN通过智能技术生成

引言:

21世纪是一个信息时代,更是一个网络全球化的时代,随着科学技术的发展,越来越多的App不光是需要和网络服务器进行数据传输和交互,也需要和其他 App 进行数据传递。承担App与网络来进行传输和存储数据的一般是XML或者JSON。在软件通信领域中XMLJSON扮演重要角。
最近一段时间,小编综合了之前在项目中对JSON的一些了解,参考了一些相关资料,把自己的一些思考融入了这篇总结文档中,同事尝试用通俗诙谐的语言风格来阐述,期望能给感兴趣的读者带来帮助。

为了不和时代落伍,我们必须积极响应和号召党的领导,所以必须要学习 JSON数据的解析和存储,其实很Easy的。

一、JSON

1.1、JSON是什么?
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它基于JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。

JSON是存储和交换文本信息的语法,类似XML
JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 这些特性使JSON成为理想的数据交换语言
1.2 、JSON格式
JSON构建于两种结构:
1.“名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组(associative array)。
2.值的有序列表(An ordered list of values)。在大多数语言中,它被理解为数组(array)、矢量(vector), 列表(list)或者是序列(sequence)。
JSON具有以下这些形式:
1.简单的一个 { ,,,,}。
2.里面有数组 { , [{,,},{,,}],}。
3.直接一个数组。
4.数组里有数组。
5.其他情况? 没有吧,除非json数据不规范。
1.3、解析json数据常用方法
包括JSONObject、JSONArray、JSONStringer、JSONTokener、JSONWriter、JSONEx。

二、JSON解析

前面讲了那么多废话其实也是必须的“毕竟十万个为什么吗“,咱们今天主要讲JSON数据格式的解析,在这呢小编先给大家看一个咱们经常用到的JSON格式的数据,这是聚合官网中“全国天气预报”请求返回的数据格式,格式稍微有点复杂不过也是我们在项目中经常用到的JSON格式,大家都清楚JSON格式的数据是由对象和数组两者结合起来的,再怎么复杂也只有这两种的结合。
JSON数据样式:
这是咱们这次从服务器请求回来的接送数据,也是咱们要解析的数据
详细解析:
(1)、首先我们从服务器请求数据,服务器返回的数据是一个封装好的JSON格式的字符串,我们将这个字符串临时保存下来以备后面解析用,这里我用到了c_str()函数,对此类型函数的详解见:string中c_str()、data()、copy(p,n)函数的用法
(2)、此代码主要用来定位每个名称,然后将对应名称的内容存储下来。

bool StructureFormatData::parseAlarmListJson(const QString& str,EntitiesBase* result,QString& message)
{
    std::string ss = ChineseTexttoStdstring(str);
    const char* json = ss.c_str();
    rapidjson::Document document;
    if (document.Parse<0>(json).HasParseError())
        return false;
    assert(document.IsObject());

    int code = 0;
    std::string mess = "";
    //add
    for(rapidjson::Document::Member* m = document.MemberBegin();m!=document.MemberEnd();++m)
    {
        std::string name = m->name.GetString();
        if(name == "code")
        {
            code = m->value.GetInt();
        }
        else if(name == "data")
        {
            for (rapidjson::SizeType i = 0; i < m->value.Size();++i)
            {
                AlarmEntity* ae = new AlarmEntity;
                for(rapidjson::Document::Member* m1 = m->value[rapidjson::SizeType(i)].MemberBegin();m1!=m->value[rapidjson::SizeType(i)].MemberEnd();++m1)
                {
                    parseAlarmJson(m1,ae);
                }
                result->addChild(ae);
            }
        }
        else if(name == "message")
        {
            std::string vs= m->value.GetString();
            message = QString::fromUtf8(vs.c_str());
        }
    }
    if(code !=1)
        return false;
    return true;
}

(3)、此代码是对json数据解析的一个封装,比较难以理解,而且代码比较长。

#ifndef RAPIDJSON_DOCUMENT_H_
#define RAPIDJSON_DOCUMENT_H_

#include "reader.h"
#include "strfunc.h"
#include <new>      // placement new

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4127) // conditional expression is constant
#endif

namespace rapidjson {

///
// GenericValue

//! Represents a JSON value. Use Value for UTF8 encoding and default allocator.
/*!
    A JSON value can be one of 7 types. This class is a variant type supporting
    these types.

    Use the Value if UTF8 and default allocator

    \tparam Encoding    Encoding of the value. (Even non-string values need to have the same encoding in a document)
    \tparam Allocator   Allocator type for allocating memory of object, array and string.
*/
#pragma pack (push, 4)
template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > 
class GenericValue {
public:
    //! Name-value pair in an object.
    struct Member { 
        GenericValue<Encoding, Allocator> name;     //!< name of member (must be a string)
        GenericValue<Encoding, Allocator> value;    //!< value of member.
    };

    typedef Encoding EncodingType;                  //!< Encoding type from template parameter.
    typedef Allocator AllocatorType;                //!< Allocator type from template parameter.
    typedef typename Encoding::Ch Ch;               //!< Character type derived from Encoding.
    typedef Member* MemberIterator;                 //!< Member iterator for iterating in object.
    typedef const Member* ConstMemberIterator;      //!< Constant member iterator for iterating in object.
    typedef GenericValue* ValueIterator;            //!< Value iterator for iterating in array.
    typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.

    //!@name Constructors and destructor.
    //@{
   

    //! Default constructor creates a null value.
    GenericValue() : flags_(kNullFlag) {}

    //! Copy constructor is not permitted.
private:
    GenericValue(const GenericValue& rhs);

public:

    //! Constructor with JSON value type.
    /*! This creates a Value of specified type with default content.
        \param type Type of the value.
        \note Default content for number is zero.
    */
    GenericValue(Type type) {
        static const unsigned defaultFlags[7] = {
            kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kConstStringFlag,
            kNumberFlag | kIntFlag | kUintFlag | kInt64Flag | kUint64Flag | kDoubleFlag
        };
        RAPIDJSON_ASSERT(type <= kNumberType);
        flags_ = defaultFlags[type];
        memset(&data_, 0, sizeof(data_));
    }

    //! Constructor for boolean value.
    GenericValue(bool b) : flags_(b ? kTrueFlag : kFalseFlag) {}

    //! Constructor for int value.
    GenericValue(int i) : flags_(kNumberIntFlag) { 
        data_.n.i64 = i;
        if (i >= 0)
            flags_ |= kUintFlag | kUint64Flag;
    }

    //! Constructor for unsigned value.
    GenericValue(unsigned u) : flags_(kNumberUintFlag) {
        data_.n.u64 = u; 
        if (!(u & 0x80000000))
            flags_ |= kIntFlag | kInt64Flag;
    }

    //! Constructor for int64_t value.
    GenericValue(int64_t i64) : flags_(kNumberInt64Flag) {
        data_.n.i64 = i64;
        if (i64 >= 0) {
            flags_ |= kNumberUint64Flag;
            if (!(i64 & 0xFFFFFFFF00000000LL))
                flags_ |= kUintFlag;
            if (!(i64 & 0xFFFFFFFF80000000LL))
                flags_ |= kIntFlag;
        }
        else if (i64 >= -2147483648LL)
            flags_ |= kIntFlag;
    }

    //! Constructor for uint64_t value.
    GenericValue(uint64_t u64) : flags_(kNumberUint64Flag) {
        data_.n.u64 = u64;
        if (!(u64 & 0x8000000000000000ULL))
            flags_ |= kInt64Flag;
        if (!(u64 & 0xFFFFFFFF00000000ULL))
            flags_ |= kUintFlag;
        if (!(u64 & 0xFFFFFFFF80000000ULL))
            flags_ |= kIntFlag;
    }

    //! Constructor for double value.
    GenericValue(double d) : flags_(kNumberDoubleFlag) { data_.n.d = d; }

    //! Constructor for constant string (i.e. do not make a copy of string)
    GenericValue(const Ch* s, SizeType length) { 
        RAPIDJSON_ASSERT(s != NULL);
        flags_ = kConstStringFlag;
        data_.s.str = s;
        data_.s.length = length;
    }

    //! Constructor for constant string (i.e. do not make a copy of string)
    GenericValue(const Ch* s) { SetStringRaw(s, internal::StrLen(s)); }

    //! Constructor for copy-string (i.e. do make a copy of string)
    GenericValue(const Ch* s, SizeType length, Allocator& allocator) { SetStringRaw(s, length, allocator); }

    //! Constructor for copy-string (i.e. do make a copy of string)
    GenericValue(const Ch*s, Allocator& allocator) { SetStringRaw(s, internal::StrLen(s), allocator); }

    //! Destructor.
    
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值