Получение значения json с помощью пути в 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" }
]}
]
}
Я только хочу вернуться
[
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/, а не окончание. Помощь в решении этого будет оценена.
1 ответ
Решение
Это - ответ на вопрос:
#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;
}