javascript - 使用 rapidjson 在 C++ 中比较 json 值

标签 javascript c++ json rapidjson

我是 javascript 开发人员,刚接触 c++。我已经用 js 编写了代码,并希望使用 rapidjson 在 c++ 中实现它。该代码的目的是将两个 json 与作为引用的第三个 json 进行比较。

import React, { Component } from 'react';
import { render } from 'react-dom';
import store from './store';
import './style.css';

class App extends Component {
  constructor() {
super();
this.state = {
  name: 'React'
};
}
testHasAllProperties(dataset) {
let mandatoryProperties = [
  "input1",
  "input2",
  "template",
  "isequal",
]
let res = true;
mandatoryProperties.map(v => {
  if (!dataset.hasOwnProperty(v)) {
    console.log('Missing Property ' + v)
    res = false
  }
})
return res
}
getInputByPath(obj, path) {
obj = JSON.parse(JSON.stringify(obj))
for (var i = 0, path = path.split('.'), len = path.length; i < len; i++) {
  obj = obj[path[i]];
};
return obj;
 };
 /*
template to iterate
current path to extract value from input
 */
iterateTemplate(template, path, output) {
for (let index in template) {
  let outputarr = []
  let datatype = Object.prototype.toString.call(template[index])

  //this.line(path + index + ' - ' + datatype + ' - ' + 
template[index] + ' - ' +datatypeval
  outputarr.push(path + index)
  outputarr.push(datatype)
  let val = this.getInputByPath(store, path + index)
  switch (datatype) {
    case "[object Undefined]":
      console.error(template, index, template[index], typeof template[index])
      break
    case "[object Array]":
      datatype += "(" + val.length + ")"
      template[index] = [template[index][0]]
      while (template[index].length < val.length) {
        template[index].push(template[index][0])
      }
    case "[object Object]":
      template[index] = this.iterateTemplate(template[index], path + index + ".", output)
      break
    default:
      template[index] = val

      outputarr.push(template[index])

      let datatypeval = Object.prototype.toString.call(val)
      outputarr.push(datatypeval)

      output.push(this.line(outputarr.join(" - ")))
      break
  }
}

return template;
}
line(value) {
return <div>{value}</div>
}
showAllDatasets() {
let datasetCount = store.length;
let output = { left: [], right: [] }
for (var i = 0; i < datasetCount; i++) {
  let testdataset = JSON.parse(JSON.stringify(store[i]));
  let template = JSON.stringify(testdataset.template)

  if (this.testHasAllProperties(testdataset) === false)
    continue;

  output.left.push(this.line(i))
  output.right.push(this.line(i))

  let template1 = testdataset.template
  this.iterateTemplate(template1, i + ".input1.", output.left)

  let template2 = JSON.parse(template)
  this.iterateTemplate(template2, i + ".input2.", output.right)

  let isequal = (JSON.stringify(template1) === JSON.stringify(template2))
  output.left.push(this.line("is equal = " + isequal))
  output.right.push(this.line(" expected is " + testdataset.isequal))


}
return output;
}
render() {
let output = this.showAllDatasets()
return (
  <div>
    <div style={{ float: "left", width: "50%" }}>{output.left}</div>
    <div style={{ float: "left", width: "50%" }}>{output.right}</div>
  </div>
);
}
}

render(<App />, document.getElementById('root'));

我正在努力寻找 c++ 中的实现逻辑,但由于我是 c++ 的新手,我需要一些帮助才能完成它。任何帮助将不胜感激。我不需要 Html,css 部分只需要在 c++ 中实现和执行的逻辑来实现它。在应用逻辑时我无法在 c++ 中找到一些功能。

到现在为止我可以检索模板的键和路径 这是我的代码:

#include <iostream>
#include "include/rapidjson/document.h"
#include "include/rapidjson/pointer.h"
#include "include/rapidjson/stringbuffer.h"

using namespace std;
using namespace rapidjson;

class json {

 public:
 static void parse(const string &item1,const string &item2,const 
 string &temp) {
    Document doc;
    doc.Parse(temp.c_str());
    Document json1;
    json1.Parse(item1.c_str());
    Document json2;
    json2.Parse(item2.c_str());

    iterate(json1,json2,doc);
    Pointer root;
    getPath(doc, root);


}
// to get all the keys in the temp
static void iterate(const Value &json1, const Value &json2, const Value &json) {
    for (Value::ConstMemberIterator iterator = json.MemberBegin(); iterator != json.MemberEnd(); iterator++) {
        cout << iterator->name.GetString() << endl;

        if (iterator->value.GetType() == kObjectType) {

            for (Value::ConstMemberIterator itr1 = iterator->value.MemberBegin();
                 itr1 != iterator->value.MemberEnd(); itr1++) {

                if (itr1->value.GetType() == kObjectType) {

                    iterate(json1,json2,itr1->value);
                } else if (itr1->value.GetType() == kArrayType) {
                    for (auto itr2 = itr1->value.Begin(); itr2 != itr1->value.End(); itr2++) {

                        if (itr2->GetType() == kArrayType || itr2->GetType() == kObjectType) {

                            iterate(json1,json2,*(itr2));
                        }
                    }
                }
            }
        } else if (iterator->value.GetType() == kArrayType) {

            for (Value::ConstValueIterator itr1 = iterator->value.Begin(); itr1 != iterator->value.End(); itr1++) {
                // cout << itr->name.GetString() << endl;
                if (itr1->GetType() == kArrayType || itr1->GetType() == kObjectType) {
                    // cout << itr->name.GetString() << endl;
                    iterate(json1,json2,*(itr1));

                }
            }
        }
    }
}
//to get the path of the keys in the temp
static void getPath(const Value& value, const Pointer& pointer) {
    if (value.IsObject())
        for (Value::ConstMemberIterator itr = value.MemberBegin(); itr != value.MemberEnd(); ++itr) {

            getPath(itr->value, pointer.Append(itr->name.GetString(), itr->name.GetStringLength()));
        }
    else if (value.IsArray()) {
        for (SizeType i = 0; i < value.Size(); i++) {
            getPath(value[i], pointer.Append(i));
        }
    }else {
        StringBuffer sb;
        pointer.Stringify(sb);
        std::cout << sb.GetString() << std::endl;
    }
}

 };

int main() {
const char *temp = "{      \"product\": \"string\",      \"version\":\"float\",      \"releaseDate\": \"string\",      \"demo\": \"bool\",      \"person\": {        \"id\": \"double\",        \"name\": \"string\",        \"phones\": {          \"home\": \"string\",          \"mobile\": \"string\"        },        \"email\": [          null        ],        \"dateOfBirth\": \"string\",        \"registered\": \"bool\",        \"emergencyContacts\": [          {            \"name\": \"string\",            \"phone\": \"string\",            \"relationship\": \"string\",            \"alternativeContacts\": [\"name\":\"string\",           null                                    ]          }        ]      }    }  }";
const char *item1 = "{      \"product\": \"Live JSON generator\",      \"version\": 3.1,      \"releaseDate\": \"2014-06-25T00:00:00.000Z\",      \"demo\": true,      \"person\": {        \"id\": 12345,        \"name\": \"John Doe\",        \"phones\": {          \"home\": \"800-123-4567\",          \"mobile\": \"877-123-1234\"        },        \"email\": [          \"jd@example.com\",          \"jd@example.org\",          \"name\": \"John Doe\",          \"demo\": true        ],        \"dateOfBirth\": \"1980-01-02T00:00:00.000Z\",        \"registered\": true,        \"emergencyContacts\": [          {            \"name\": \"Jane Doe\",            \"phone\": \"888-555-1212\",            \"relationship\": \"spouse\",            \"alternativeContacts\": [              \"test\",              \"123\",              \"some\\\"char\"            ]          },          {            \"name\": \"Justin Doe\",            \"phone\": \"877-123-1212\",            \"relationship\": \"parent\",            \"alternativeContacts\": [\"name\": \"John Doe\",              \"demo\": true,              3,              null            ]          }        ]      }    }";
const char *item2 = "{      \"product\": \"Live JSON generator\",      \"version\": 3.1,      \"releaseDate\": \"2014-06-25T00:00:00.000Z\",      \"demo\": true,      \"person\": {        \"id\": 12345,        \"name\": \"John Doe\",        \"phones\": {          \"home\": \"800-123-4567\",          \"mobile\": \"877-123-1234\"        },        \"email\": [          \"demo\": true,          \"name\": \"John Doe\",          \"jd@example.com\",          \"jd@example.org\"        ],        \"dateOfBirth\": \"1980-01-02T00:00:00.000Z\",        \"registered\": true,        \"emergencyContacts\": [          {            \"name\": \"Jane Doe\",            \"phone\": \"888-555-1212\",            \"relationship\": \"spouse\",            \"alternativeContacts\": [              \"test\",              \"123\",              \"some\\\"char\"            ]          },          {            \"name\": \"Justin Doe\",            \"phone\": \"8774-123-1212\",            \"relationship\": \"parent\",            \"alternativeContacts\": [\"name\": \"John Doe\",              \"demo\": true,              4,              null            ]          }        ]      }    }";

json::parse(item1,item2,temp);
}

我们将不胜感激。

最佳答案

这是问题的答案,适用于每种情况,没有错误。

#include <iostream>
#include "include/rapidjson/document.h"
#include "include/rapidjson/pointer.h"
#include "include/rapidjson/writer.h"
#include "strings.h"
#include "cstring"


using namespace std;
using namespace rapidjson;

class test {

public:
static bool parseJson(const string &json1, const string &json2, const 
string &temp) {
    Document d;
    d.Parse(json1.c_str());
    Document d1;
    d1.Parse(json2.c_str());
    Document d2;
    d2.Parse(temp.c_str());

    Pointer root;
    bool match = getPath(d,d1, d, d1, d2, root);

    return match;
}

static bool getPath(const Value &item1, const Value &item2, const Value &value, const Value &value1, const Value &v, const Pointer &parent) {
    bool match = true;


    if (v.IsObject())
        for (Value::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) {

            if(value.HasMember(itr->name)&&value1.HasMember(itr->name)) {
                match = getPath(item1,item2, value[itr->name.GetString()], value1[itr->name.GetString()], itr->value, parent.Append(itr->name.GetString()));

            }
            else{
                match=false;
                break;
            }

            if (match == 0) {
                break;
            }
        }
    else if (v.IsArray()) {
        auto len = v.Size();
        auto len1 = value.Size();

        cout<<"length of item1:"<<len1<<endl;
        auto len2=value1.Size();
        cout<<"length of item 2:"<<len2<<endl;
        SizeType i = 0;


        for (SizeType i = 0; i < len; i++) {
            if(len>len1||len1!=len2){
                match=false;
                break;
            }
           else  if (len == len1) {
                match = getPath(item1,item2, value[i], value1[i], v[i], parent.Append(i));

                if (match == 0) {
                    break;
                }
            }
            else {
                for (SizeType j = 0; j <= len; j++) {
                    match = getPath(item1,item2, value[j], value1[j], v[i], parent.Append(j));
                    if (match == 0) {
                        break;
                    }
                }
            }

        }
    } else {

        StringBuffer sb;
        parent.Stringify(sb);

        string path = getPaths(sb.GetString());

        cout<<"paths:"<<path<<endl;

        string val = findValue(item1, path);

        cout<<"value1:"<<val<<endl;
        string val1 = findValue(item2, path);

        cout<<"value2:"<<val1<<endl;

        if (val != val1||val=="Dont have the key in the json"||val1=="Dont have the key in the json") {

            match = false;
            return match;

        }
    }

    return match;
}

static string getPaths(string path) {
    path = path.erase(0, 1);
    path = path + "/";
    return path;
}

static string findValue(const Value &item, string path) {

    StringBuffer s1;
    Writer<StringBuffer> w1(s1);
    item.Accept(w1);

    cout << "value recursed:" << s1.GetString() << endl;

    string delimiter = "/";
    size_t pos = 1;
    string keys, paths, result;

    keys = path.substr(0, path.find(delimiter));

    if(path.length()>1) {
        if (item.HasMember(keys.c_str())) {
            const Value &element = item[keys.c_str()];
            StringBuffer s;
            Writer<StringBuffer> w(s);
            element.Accept(w);


            paths = path.erase(0, keys.length() + 1);

            if (paths.length() > 1) {
                if (element.IsObject()) {
                    StringBuffer s1;
                    Writer<StringBuffer> w1(s1);
                    element.Accept(w1);

                    cout << "value sent:" << s1.GetString() << endl;
                    cout << "Paths:" << paths << endl;
                    result = findValue(element, paths);
                } else if (element.IsArray()) {
                    string token = path.substr(0, path.find(delimiter));

                    int key = stoi(token);

                    paths = paths.erase(0, token.length() + 1);
                    if (element[key].IsArray() || element[key].IsObject()) {

                        result = findValue(element[key], paths);


                    } else {

                        StringBuffer s1;
                        Writer<StringBuffer> w1(s1);
                        element.Accept(w1);

                        // cout << "value sent:" << s1.GetString() << endl;
                        return s1.GetString();
                    }
                }

            } else {

                // cout << "Value sent outside:" << s.GetString() << endl;
                return s.GetString();
            }
        } else {
            result = "Dont have the key in the json";
            return result;
        }
    }else{
        return s1.GetString();
    }
    return result;
}
};

int main() {
const char *item1 = "{  \"array\": [    { \"x\": [1,2,2]},    2,    3  
 ]}";
const char *item2 = "{  \"array\": [    { \"x\": [1,2,2]},   2,    3  
]}";
const char *temp = "{  \"array\": [    null  ]}";

bool match = test::parseJson(item1, item2, temp);
cout << match;
}

关于javascript - 使用 rapidjson 在 C++ 中比较 json 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50146859/

相关文章:

javascript - Trello 卡片更新 API

javascript - 带有 Fancybox 的 Pikachoose API Hook 在 IE9 或更低版本中不起作用

c++ - shared_ptr & weak_ptr 转换

javascript - 使用 ajax 从数据库 EntityFramework 中删除记录

c++ - 什么时候可以安全地重复使用来自普通可破坏对象的内存而不洗

c++ - 使用正则表达式比较字符串

c# - AJAX 调用不从 WebMethod 返回 JSON 对象

javascript - 如何浏览 JSON 节点结构

python - 如何在添加另一个字段时从数据框中传递嵌套的 JSON?

javascript - 如何重写 javascript 库对象 this.function(arg, function(){