【问题标题】:json Comparison in c++c++中的json比较
【发布时间】:2018-04-20 09:01:21
【问题描述】:

我有点卡在这里,谁能帮忙。

#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-&gt;name],v1[itr-&gt;name],v2[itr-&gt;name],a); 问题出在找到键是一个数组后我想使用递归深入嵌套数组并在其中迭代(即在遇到它的数组后我想将整个数组递归为解析的 json 以在内部循环并比较每个键。 或者我们可以为现有 json 中的数组创建一个新的 json 并递归该值来检查它吗?请对此有一些想法。

【问题讨论】:

  • 不清楚你的方法isEqual应该做什么。 temp 建议是临时的,但它不是...ref 似乎是一个更好的名字。
  • temp 是一个 json 模式,将基于它对 input1 和 input2 进行比较。isEqual() 将用于比较字符串,但比较将在 isJsonEqual() 中完成我想用递归来比较更深的嵌套数组

标签: c++ json rapidjson


【解决方案1】:

据我了解,代码应该是这样的:

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");
        }
    }
}

【讨论】:

  • 这是用jsoncpp吗?
  • 是的。我没有编译代码,所以可能有一些错误/错别字。
  • 是的,使用 jsoncpp 我得到了错误,但逻辑看起来不错,希望它能工作(只想根据模式或参考 json 比较 input1 和 input2,能够做到但无法做到获取那些嵌套的键,如果在引用 json 中缺少一些更深的数组键但不是必需的,那么逻辑将失败,它会说 input1 和 input2 不相等,但根据它应该是的逻辑)。如果他们有像 jsoncpp 这样的功能,我可以让它在 rapidjson 上工作。谢谢。
  • 它正在比较类型,但我想获取内部键并迭代以检查它们的值
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-29
  • 2021-03-01
  • 2012-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多