如果密钥有效,如何检查 Json 文件并使用 RapidJson 在 C++ 中创建对象数组
How to check Json File if the keys are valid and create a array of objects in c++ with RapidJson
我正在尝试使用 rapidjson 从 json 文件创建一个 class/struct 数组。该文件包含以下内容:
{
"item" : [
{"name": "chair",
"attribute": "iron",
"available": "false"},
{"Name": "bed",
"attribute": "wood",
"available": "true",
"attribute":"soft"},
{"naeM": "lamp",
"attribute": "iron",
"available": "false",
"Number": "4"},
....
{"name": "mirrow",
"attribute": "iron",
"available": "false"}
],
"category" : [
{"name": "kitchen"}, {"name": "living room"},{"name": "bedroom"} ]
}
我已经查阅了所有关于 rapidjson.org 和示例的信息,但并没有真正了解如何检查每个验证数组对象中的特定键(如果键存在(区分大小写) ) 并且对象中没有重复项。
例如,这里我想检查每个数组对象中是否有键"name",或者是否只有键"name"、"attribute"和"available"当下。到达那里的封闭可能是创建一个 json 模式有效检查,但我真的不明白它的语法。
这是一个简单的程序,它检查每个 item
是否具有这三个属性:
#define RAPIDJSON_HAS_STDSTRING 1
#include "rapidjson/document.h"
#include "rapidjson/istreamwrapper.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <iterator>
using namespace rapidjson;
using namespace std;
bool check_or_error(bool check, string message) {
if (!check) {
cerr << message << endl;
}
return check;
}
int main() {
Document doc;
{
// This just loads JSON from a file into `doc`.
ifstream fs("test2.json");
IStreamWrapper isw(fs);
doc.ParseStream(isw);
if (doc.HasParseError()) {
cerr << "Parse error " << doc.GetParseError() << " at " << doc.GetErrorOffset();
exit(1);
}
}
// Grab the element under `item` and coerce it to an array.
const Value::Array& a = doc["item"].GetArray();
// This is a standard iterator pattern; we set `it` equal to every element
// in turn. We use `cbegin`/`cend` to get const iterators, which do not
// modify the array.
for (auto it = cbegin(a); it != cend(a); it++) {
bool ok = true;
// Is it an object? if not, complain and move to the next element.
ok = check_or_error(it->IsObject(), "Item is not an object");
if (!ok) continue;
const Value::Object& item = it->GetObject();
int idx = std::distance(cbegin(a), it);
static std::string mandatory[] = { "name", "attribute", "available" };
// For every mandatory key ...
for (const auto& key : mandatory) {
// ... check if it is present or complain
// The weird `(stringstream() << ...).str()` construct
// allows us to creata formatted message as a string.
ok = check_or_error(item.HasMember(key), (stringstream() << "item[" << idx << "] missing key " << key).str());
if (!ok) continue;
// ... check if it is a string or complain
const Value& v = item[key];
check_or_error(v.IsString(), (stringstream() << "item[" << idx << "][" << key << " not a string ").str());
}
}
}
请注意,它不会检查重复键,因为 RapidJSON 会为您隐藏它。
相应的 JSONSchema 将是:(test for yourself)
{
"type": "object",
"required": [
"item",
"category"
],
"properties": {
"item": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"attribute",
"available"
],
"properties": {
"name": {
"type": "string"
},
"attribute": {
"type": "string"
},
"available": {
"type": "string"
}
}
}
},
"category": {
"type": "array",
"items": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
}
}
}
}
}
}
我正在尝试使用 rapidjson 从 json 文件创建一个 class/struct 数组。该文件包含以下内容:
{
"item" : [
{"name": "chair",
"attribute": "iron",
"available": "false"},
{"Name": "bed",
"attribute": "wood",
"available": "true",
"attribute":"soft"},
{"naeM": "lamp",
"attribute": "iron",
"available": "false",
"Number": "4"},
....
{"name": "mirrow",
"attribute": "iron",
"available": "false"}
],
"category" : [
{"name": "kitchen"}, {"name": "living room"},{"name": "bedroom"} ]
}
我已经查阅了所有关于 rapidjson.org 和示例的信息,但并没有真正了解如何检查每个验证数组对象中的特定键(如果键存在(区分大小写) ) 并且对象中没有重复项。
例如,这里我想检查每个数组对象中是否有键"name",或者是否只有键"name"、"attribute"和"available"当下。到达那里的封闭可能是创建一个 json 模式有效检查,但我真的不明白它的语法。
这是一个简单的程序,它检查每个 item
是否具有这三个属性:
#define RAPIDJSON_HAS_STDSTRING 1
#include "rapidjson/document.h"
#include "rapidjson/istreamwrapper.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <iterator>
using namespace rapidjson;
using namespace std;
bool check_or_error(bool check, string message) {
if (!check) {
cerr << message << endl;
}
return check;
}
int main() {
Document doc;
{
// This just loads JSON from a file into `doc`.
ifstream fs("test2.json");
IStreamWrapper isw(fs);
doc.ParseStream(isw);
if (doc.HasParseError()) {
cerr << "Parse error " << doc.GetParseError() << " at " << doc.GetErrorOffset();
exit(1);
}
}
// Grab the element under `item` and coerce it to an array.
const Value::Array& a = doc["item"].GetArray();
// This is a standard iterator pattern; we set `it` equal to every element
// in turn. We use `cbegin`/`cend` to get const iterators, which do not
// modify the array.
for (auto it = cbegin(a); it != cend(a); it++) {
bool ok = true;
// Is it an object? if not, complain and move to the next element.
ok = check_or_error(it->IsObject(), "Item is not an object");
if (!ok) continue;
const Value::Object& item = it->GetObject();
int idx = std::distance(cbegin(a), it);
static std::string mandatory[] = { "name", "attribute", "available" };
// For every mandatory key ...
for (const auto& key : mandatory) {
// ... check if it is present or complain
// The weird `(stringstream() << ...).str()` construct
// allows us to creata formatted message as a string.
ok = check_or_error(item.HasMember(key), (stringstream() << "item[" << idx << "] missing key " << key).str());
if (!ok) continue;
// ... check if it is a string or complain
const Value& v = item[key];
check_or_error(v.IsString(), (stringstream() << "item[" << idx << "][" << key << " not a string ").str());
}
}
}
请注意,它不会检查重复键,因为 RapidJSON 会为您隐藏它。
相应的 JSONSchema 将是:(test for yourself)
{
"type": "object",
"required": [
"item",
"category"
],
"properties": {
"item": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"attribute",
"available"
],
"properties": {
"name": {
"type": "string"
},
"attribute": {
"type": "string"
},
"available": {
"type": "string"
}
}
}
},
"category": {
"type": "array",
"items": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
}
}
}
}
}
}