RapidJSON 迭代器、成员和对象的困难

问题描述

我似乎不明白如何递归下降文档以有选择地更新键值对。

我有一个 JSON 文档,请参阅下面代码中的“文档”。我想逐步更新“文档”,只需定义那些更改的字段。

增量定义为两部分,“delta_key”和“delta_value”。

我编写的代码对于平面 JSON 结构正确执行此操作。

如果我将一个数组添加到“document”,现在是“document2”,当我迭代“delta2_value”时,我需要对数组或对象进行递归。

我遇到的问题是能够使用 FindMember() 的结果进行递归。 FindMember() 返回一个指向成员的指针,其中迭代器是一个指向值的指针。

我不知道如何创建第一个参数。 //jtest_ProcessArray(*domkey_objectiter,itr); [如所写给编译器错误]

我在rapidjson 上读到的许多示例都是“只读”示例。我找不到“更新”示例。

copyFrom() 不能使用,因为更新中缺少键值对,它们将在文档中丢失。


#include "rapidjson/pointer.h"

using namespace rapidjson;

typedef rapidjson::GenericDocument<rapidjson::UTF8<>,rapidjson::CrtAllocator> JsonDocument;
typedef rapidjson::GenericValue<rapidjson::UTF8<>,rapidjson::CrtAllocator> JsonValue;
typedef rapidjson::GenericPointer<JsonValue,rapidjson::CrtAllocator> jsonpointer;
typedef rapidjson::Genericmember<JsonValue,rapidjson::CrtAllocator> JsonMember;
typedef rapidjson::GenericValue<rapidjson::UTF8<>,rapidjson::CrtAllocator>::Object JsonObject;
typedef rapidjson::GenericValue<rapidjson::UTF8<>,rapidjson::CrtAllocator>::ValueIterator JsonValueItr;

const char *document =
        R"( { "device" : { "speed" : 100,"accel": 10,"count": 2,"depth": 10,"delay": 10 }})";

const char *delta_key =
        "device";

const char *delta_value= R"( {"depth" : 5,"delay": 2 })";

const char *document2 =
        R"( { "device" : { "speed" : 100,"accel" : 10,list" :[{"count": 2,"delay": 10 },{"count": 4,"depth": 1,"delay": 5})";

const char *delta2_key =
        "device";

const char *delta2_value= R"( "accel" : 5,"list": [{"depth" : 5},{"delay": 2 }])";

static bool setJsonValue(JsonValue *dom,const JsonValue* jsonValue)
{
    if (jsonValue->IsNumber()) {
        if (jsonValue->IsInt()) {
            int vint = jsonValue->GetInt();
            dom->SetInt(vint);
        } else if (jsonValue->IsUint()) {
            unsigned int uint = jsonValue->GetUint();
            dom->SetUint(uint);
        } else if (jsonValue->IsFloat() || jsonValue->IsDouble()) {
            float vfloat = jsonValue->GetFloat();
            dom->SetFloat(vfloat);
        }
    }
    else if(jsonValue->IsFalse()) {
        dom->SetBool(false);
    }
    else if(jsonValue->IsTrue()) {
        dom->SetBool(true);
    }
    else {
        SizeType length = jsonValue->GetStringLength();
        dom->SetString(jsonValue->GetString(),length);
    }
    return false;
}

bool jtest_ProcessArray(JsonValue *dom,const JsonValue *updateValue);

bool jtest_ProcessObject(JsonValue *dom,const JsonValue *updateValue)
{
    bool bSuccess = false;

    for (const auto& itr : updateValue->Getobject()) {
        auto domkey_objectiter = dom->FindMember(itr.name);
        if(domkey_objectiter != dom->MemberEnd()) {
            rapidjson::Type type = domkey_objectiter->value.GetType();
            if(type == itr.value.GetType()) {
                if(type == kArrayType ) {
                    printf("Array type found\r\n");
                    //jtest_ProcessArray(*domkey_objectiter,itr);
                }
                else if(type == kObjectType)
                {
                    printf("Object type found\r\n");
                    //JsonValue& jvalue = *dom[itr.name];
                    //jtest_ProcessObject(*domkey_objectiter,itr);
                }

                else {
                    setJsonValue(&domkey_objectiter->value,&itr.value);
                }
            }
        }
    }
    return bSuccess;
}

bool jtest_ProcessArray(JsonValue *dom,const JsonValue *updateValue)
{
    bool bSuccess = false;

    // To be completed like ProcessObject()
    return bSuccess;
}

int jsontest()
{
    bool bSuccess = false;
    int retVal;
    JsonDocument dom;
    dom.Parse(document);

    JsonDocument update;

    auto keyptr = jsonpointer(delta_key);

    auto docupdateptr = keyptr.Get(dom);
    if (docupdateptr) {
        JsonDocument update_value;
        update_value.Parse(delta_value);
        if(update_value.IsObject()) {
            bSuccess = jtest_ProcessObject(docupdateptr,&update_value);
        }
        else if(update_value.IsArray()) {
            bSuccess = jtest_ProcessArray(docupdateptr,&update_value);
        }
    }
    if(bSuccess) {
        retVal = 0;
    }
    else {
        retVal = 1;
    }
    return retVal;
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)