Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
155 views
in Technique[技术] by (71.8m points)

json Comparison in c++

I am a little stuck here can anyone help please.

#include <iostream>
#include "include/rapidjson/document.h"
#include "include/rapidjson/writer.h"
#include "include/rapidjson/prettywriter.h"
//#include "include/rapidjson/stringbuffer.h"
using namespace std;
using namespace rapidjson;

class test {
 public:
static bool isEqual(const string &item1, const string &item2, const string &temp) {
    Document d1;
    d1.Parse(item1.c_str());
    Document d2;
    d2.Parse(item2.c_str());
    Document d3;
    d3.Parse(temp.c_str());
    bool a = true;
    bool b = isJsonEqual(d1, d2, d3, a);

}

static bool isJsonEqual(Value &v, Value &v1, Value &v2, bool &a) {
/*
    StringBuffer buffer;


    PrettyWriter<StringBuffer> writer(buffer);


    v.Accept(writer);
    //cout<<buffer.GetString()<<endl;
    StringBuffer b1;
    PrettyWriter<StringBuffer> writer1(b1);
    v1.Accept(writer1);
    //cout<<b1.GetString()<<endl;
    StringBuffer b2;
    PrettyWriter<StringBuffer> writer2(b2);
    v2.Accept(writer2);
     //cout<<b2.GetString()<<endl;
  */

    for (auto itr = v2.MemberBegin(); itr != v2.MemberEnd(); itr++) {
        if (itr->value.IsArray()) {
           StringBuffer b3;
            PrettyWriter<StringBuffer> writer3(b3);
            v2[itr->name].Accept(writer3);
            cout << b3.GetString() << endl;
            auto c = itr->name.GetString();

            cout << c << endl;

     //isJsonEqual(v[itr->name],v1[itr->name],v2[itr->name],a);
        } else if (v.HasMember(itr->name) && v1.HasMember(itr->name)) {
            // cout<<itr->name.GetString()<<endl;
            if ((v[itr->name]) != v1[itr->name]) {


                a = false;
                break;
            }
        }
    }

}


};

 int main() {
  const char *input1 = "{  "array": [    1,    2,    3  ],  
 "boolean": true,  "null": null,  "number": 123,  "object": {    
 "a": "b",    "c": "d",    "e": "f"  },  "string": 
 "Hello World",   "object_array": [     {"key": "value1" },     
 {"key": "value2" },     {"key": "value3" }    ],    
 "deep_nested_array": [        {"object_array1": [     {"key": 
 "value1" },     {"key": "value2" },     {"key": "value3" }    
 ]},    {"object_array2": [     {"key": "value4" },     
 {"key": "value5" },     {"key": "value6" }    ]}      ]}";

const char *input2= "{ "array": [    1,    2,    3  ],   
"justsomedata": true,  "boolean": true,  "null": null,  
"object": {    "a": "b",    "c": "d",    "e": "f"  },  
"number": 123,  "object_array": [     {"whatever": "test", 
 "key": "value1" },     {"key": "value2" },     {"key": 
 "value3" }    ],    "deep_nested_array": [        
 {"object_array1": [     {"key": "value1" },     {"key": 
 "value2" },     {"key": "value3" }    ]},    
 {"object_array2": [     {"key": "value4" },     {"key": 
 "value5" },     {"key": "value6", "ignoreme": 12346 }    ]}      
  ],  "string": "Hello World"}";
  const char *temp = "{  "array": [    null  ],  "boolean": null,  
 "null": null,  "object": {    "a": null,    "c": null,    
 "e": null  },  "number": null,  "object_array": [     {"key": 
 null }    ],    "deep_nested_array": [        {"object_array1": [     
 {"key": null },     {"key": null },     {"key": null }    ]}      
 ],  "string": null}";

bool a = test::isEqual(input1, input2, temp);
if (a) {
    cout << "True";
    //std::cout << "Verify again" << std::endl;
} else {
    cout << "check again";
}
       }

//isJsonEqual(v[itr->name],v1[itr->name],v2[itr->name],a); The problem lies here after finding the key is an array I want to use recursion to go deep into nested array and iterate in it(ie after I encounter its an array I want to recurse the entire array as a parsed json to loop inside and compare each keys. Or can we create a new json for the arrays in the existing json and recurse the value to check it?please need some ideas with this.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As I understand, the code should be something like:

bool isJsonEqual(const Json::Value &reference, Json::Value &v1, Json::Value &v2)
{
    switch (reference.GetType()) {
        case Json::Value::booleanValue: {
             if (reference.asBool()) {
                 return v1 == v2;
             } else {
                 return true; // don't check comparison
             }
        }
        case Json::Value::nullValue : return true; // don't check comparison
        case Json::Value::arrayValue: {
            if (v1.GetType() != Json::Value::arrayValue
             || v2.GetType() != Json::Value::arrayValue) {
                 return false;
            }
            const auto size = reference.ArraySize();
            if (v1.ArraySize() != size || v2.ArraySize() != size) {
                 return false;
            }
            // Recurse on array
            for (std::size_t i = 0; i != size; ++i) {
                 if (!isJsonEqual(reference[i], v1[i], v2[i])) {
                     return false;
                 }
            }
            return true;
        }
        case Json::Value::objectValue: {
            if (v1.GetType() != Json::Value::objectValue
             || v2.GetType() != Json::Value::objectValue) {
                 return false;
            }
            // Recurse on members
            for (const auto& member : reference.getMemberNames()) {
                 if (!isJsonEqual(reference[member], v1[member], v2[member])) {
                     return false;
                 }
            }
            return true;
        }
        default: {
            throw std::runtime_error("Invalid reference");
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...