借助 C++ 中的路径检索 json 值

Retriving json value with the help of path in c++

我目前正在开展一个项目,通过从 json 模式获取的路径从 Json 检索值,因为我只想获取存在于json 来自 Json.

的架构

我需要检索值的路径:

/array/0
/boolean
/null
/object/a
/object/c
/object/e
/number
/deep_nested_array/0/object_array1/0/key4
/deep_nested_array/0/object_array1/1/key5
/deep_nested_array/0/object_array1/2/key6
/object_array/0/key1
/object_array/1/key2
/object_array/2/key3
/string

Json 我想从中检索值的位置:

{
 "array": [
   1,
   2,
   3
],
"boolean": true,
"null": null,
"number": 123,
"object": {
  "a": "b",
  "c": "d",
  "e": "f"
 },
 "string": "Hello World", 
 "object_array": [
    {"key1": "value1" },
    {"key2": "value2" },
    {"key3": "value3" }
    ],
  "deep_nested_array": [
       {"object_array1": [
          {"key4": "value4" },
          {"key5": "value5" },
          {"key6": "value6" }
       ]}
        ,
       {"object_array2": [
          {"key7": "value7" },
          {"key8": "value8" },
          {"key9": "value9" }
       ]}
     ]
 }

我只想return

[
   1,
   2,
   3
]
true
null
b
d
f
123
Hello World
value1
value2
value3
value4
value5
value6

顺序将取决于传递的路径,无关紧要。

我的代码

  static string findValue(const Value &item, string path) {
    StringBuffer s1;
    Writer<StringBuffer> w1(s1);
    item.Accept(w1);
    cout << "recursing:" << s1.GetString() << endl;
    cout << "Original Path:" << path << endl;
    string delimiter = "/";
    size_t pos = 1;
    string token, paths;

    token = path.substr(0, path.find(delimiter));
    cout << "token:" << token << endl;
    const Value &element = item[token.c_str()];
    StringBuffer s;
    Writer<StringBuffer> w(s);
    element.Accept(w);
    cout << "items matching the token:" << s.GetString() << endl;
    while ((pos = path.find(delimiter)) <= path.find(delimiter)) {
        paths = path.erase(0, pos + delimiter.length());
        cout << "paths:" << paths << endl;


        if (paths.length() > 1) {
            if (element.IsObject()) {


                findValue(element, paths);
            } else if (element.IsArray()) {

                for (SizeType i = 0; i < element.Size(); i++) {
                    if (element[i].IsArray() || element[i].IsObject()) {
                        findValue(element[i], paths);
                    } else {
                        cout << "Array returning:" << s.GetString() << endl;
                        return s.GetString();
                    }
                }
            }

        } else {
            cout << "item returningg:" << s.GetString() << endl;
            return s.GetString();

        }
    }

}

我的输出

recursing:{"array": 
[1,2,3],"boolean":true,"null":null,"number":123,"object": 
{"a":"b","c":"d","e":"f"},"string":"Hello World","object_array": 
[{"key1":"value1"},{"key2":"value2"}, 
{"key3":"value3"}],"deep_nested_array":[{"object_array1": 
[{"key4":"value1"},{"key5":"value2"},{"key6":"value3"}]}, 
{"object_array2":[{"key7":"value4"},{"key8":"value5"}, 
{"key9":"value6"}]}]}

Original Path:array/
token:array
items matching the token:[1,2,3]
paths:
item returningg:[1,2,3]

recursing:{"array": 
[1,2,3],"boolean":true,"null":null,"number":123,"object": 
{"a":"b","c":"d","e":"f"},"string":"Hello World","object_array": 
[{"key1":"value1"},{"key2":"value2"}, 
{"key3":"value3"}],"deep_nested_array":[{"object_array1": 
[{"key4":"value1"},{"key5":"value2"},{"key6":"value3"}]}, 
{"object_array2":[{"key7":"value4"},{"key8":"value5"}, 
{"key9":"value6"}]}]}

Original Path:boolean/
token:boolean
items matching the token:true
paths:
item returningg:true

recursing:{"array": 
[1,2,3],"boolean":true,"null":null,"number":123,"object": 
{"a":"b","c":"d","e":"f"},"string":"Hello World","object_array": 
[{"key1":"value1"},{"key2":"value2"}, 
{"key3":"value3"}],"deep_nested_array":[{"object_array1": 
[{"key4":"value1"},{"key5":"value2"},{"key6":"value3"}]}, 
{"object_array2":[{"key7":"value4"},{"key8":"value5"}, 
{"key9":"value6"}]}]}

Original Path:null/
token:null
items matching the token:null
paths:
item returningg:null

 recursing:{"array": 
[1,2,3],"boolean":true,"null":null,"number":123,"object": 
{"a":"b","c":"d","e":"f"},"string":"Hello World","object_array": 
[{"key1":"value1"},{"key2":"value2"}, 
{"key3":"value3"}],"deep_nested_array":[{"object_array1": 
[{"key4":"value1"},{"key5":"value2"},{"key6":"value3"}]}, 
{"object_array2":[{"key7":"value4"},{"key8":"value5"}, 
{"key9":"value6"}]}]}

Original Path:object/a/
token:object
items matching the token:{"a":"b","c":"d","e":"f"}
paths:a/
recursing:{"a":"b","c":"d","e":"f"}

Original Path:a/
token:a
items matching the token:"b"
paths:
item returningg:"b"
paths:
item returningg:{"a":"b","c":"d","e":"f"} //Dont need this to be 
                                            returned
recursing:{"array": 
[1,2,3],"boolean":true,"null":null,"number":123,"object": 
{"a":"b","c":"d","e":"f"},"string":"Hello World","object_array": 
[{"key1":"value1"},{"key2":"value2"}, 
{"key3":"value3"}],"deep_nested_array":[{"object_array1": 
[{"key4":"value1"},{"key5":"value2"},{"key6":"value3"}]}, 
{"object_array2":[{"key7":"value4"},{"key8":"value5"}, 
{"key9":"value6"}]}]}

Original Path:object/c/
token:object
items matching the token:{"a":"b","c":"d","e":"f"}
paths:c/
recursing:{"a":"b","c":"d","e":"f"}
Original Path:c/
token:c
items matching the token:"d"
paths:
item returningg:"d"
paths:
item returningg:{"a":"b","c":"d","e":"f"}

recursing:{"array": 
[1,2,3],"boolean":true,"null":null,"number":123,"object": 
{"a":"b","c":"d","e":"f"},"string":"Hello World","object_array": 
[{"key1":"value1"},{"key2":"value2"}, 
{"key3":"value3"}],"deep_nested_array":[{"object_array1": 
[{"key4":"value1"},{"key5":"value2"},{"key6":"value3"}]}, 
{"object_array2":[{"key7":"value4"},{"key8":"value5"}, 
{"key9":"value6"}]}]}

Original Path:object/e/
token:object
items matching the token:{"a":"b","c":"d","e":"f"}
paths:e/
recursing:{"a":"b","c":"d","e":"f"}
Original Path:e/
token:e
items matching the token:"f"
paths:
item returningg:"f"
paths:
item returningg:{"a":"b","c":"d","e":"f"}

recursing:{"array": 
[1,2,3],"boolean":true,"null":null,"number":123,"object": 
{"a":"b","c":"d","e":"f"},"string":"Hello World","object_array": 
[{"key1":"value1"},{"key2":"value2"}, 
{"key3":"value3"}],"deep_nested_array":[{"object_array1": 
[{"key4":"value1"},{"key5":"value2"},{"key6":"value3"}]}, 
{"object_array2":[{"key7":"value4"},{"key8":"value5"}, 
{"key9":"value6"}]}]}

 Original Path:number/
 token:number
 items matching the token:123
 paths:
 item returningg:123
 recursing:{"array": 
 [1,2,3],"boolean":true,"null":null,"number":123,"object": 
 {"a":"b","c":"d","e":"f"},"string":"Hello World","object_array": 
 [{"key1":"value1"},{"key2":"value2"}, 
 {"key3":"value3"}],"deep_nested_array":[{"object_array1": 
 [{"key4":"value1"},{"key5":"value2"},{"key6":"value3"}]}, 
 {"object_array2":[{"key7":"value4"},{"key8":"value5"}, 
 {"key9":"value6"}]}]}

 Original Path:deep_nested_array/object_array1/key4/
 token:deep_nested_array
 items matching the token:[{"object_array1":[{"key4":"value1"}, 
 {"key5":"value2"},{"key6":"value3"}]},{"object_array2":[ 
 {"key7":"value4"},{"key8":"value5"},{"key9":"value6"}]}]

 paths:object_array1/key4/

 recursing:{"object_array1":[{"key4":"value1"},{"key5":"value2"}, 
 {"key6":"value3"}]}
 Original Path:object_array1/key4/
 token:object_array1
 items matching the token:[{"key4":"value1"},{"key5":"value2"}, 
 {"key6":"value3"}]
 paths:key4/
 recursing:{"key4":"value1"}
 Original Path:key4/
 token:key4
 items matching the token:"value1"
 paths:
 item returningg:"value1"

 recursing:{"key5":"value2"}
 Original Path:key4/
 token:key4

 validationjson: 
 /home/mavericks/CLionProjects/validationjson/ 
 include/rapidjson/document.h 
:1137: rapidjson::GenericValue<Encoding, Allocator>& 
 rapidjson::GenericValue<Encoding, Allocator>::operator[](const 
 rapidjson::GenericValue<Encoding, SourceAllocator>&) [with 
 SourceAllocator 
 = rapidjson::MemoryPoolAllocator<>; Encoding = rapidjson::UTF8<>; 
 Allocator = rapidjson::MemoryPoolAllocator<>]: Assertion `false' 
 failed.

This error is because the for loop for the IsArray is continuing with 

令牌作为键 4,路径作为键 4/ 而不是结尾。 帮助解决这个问题将不胜感激。

这是问题的答案:

#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;
}