我正在制作一个物理软件,我们部署了一个 json 解决方案,我想使用 json 模式。因此,当我有一个错误的密钥时,典型地在模式中查找“长度”,并且用户给出了诸如“length2”之类的错误信息。我实际上不知道如何用rapidjson获取它,我得到了这些结果
Invalid schema: #/properties/TEST
Invalid keyword: required
Invalid document: #/TEST
但我希望缺少像“length”键这样的输出,以便通知用户。
我的test.json文件:
{
"$schema": "./schema.json",
"TEST": {
"Length2": {
"Value":20,
"Unit":"mm"
}
}
}
编辑以下 Ether 注释我的 schema.json 但这不会改变我的输出,请参阅“无效架构”
{
"type": "object",
"required": ["TEST"],
"properties": {
"TEST": {
"type": "object",
"required": ["Length"],
"properties": {
"Length":{
"type": "object",
"required": ["Value","Unit"],
"properties": {
"Value": {"type": "number"},
"Unit": {"type": "string"}
}
}
}
}
}
}
和我的cpp代码:
#include "rapidjson/document.h"
#include "rapidjson/error/en.h"
#include "rapidjson/schema.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/filereadstream.h"
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
using namespace rapidjson;
int main()
{
char readBuffer[65536];
FILE* fp = fopen("test.json", "r");
FileReadStream is(fp, readBuffer, sizeof(readBuffer));
Document d;
d.ParseStream(is);
FILE* fp2 = fopen("schema.json", "r");
FileReadStream fs(fp2, readBuffer, sizeof(readBuffer));
Document sd;
sd.ParseStream(fs);
SchemaDocument schema(sd);
SchemaValidator validator(schema);
if(!d.Accept(validator))
{
rapidjson::StringBuffer sb;
validator.GetInvalidSchemaPointer().StringifyUriFragment(sb);
printf("Invalid schema: %s\n", sb.GetString());
printf("Invalid keyword: %s\n", validator.GetInvalidSchemaKeyword());
sb.Clear();
validator.GetInvalidDocumentPointer().StringifyUriFragment(sb);
printf("Invalid document: %s\n", sb.GetString());
}
else
printf("\nJson file validated with the given schema successfully\n");
return 0;
}
在
/properties/TEST/properties
,您应该有属性名称,而不是模式。也许您缺少包含该子模式的 "Length"
属性?
所以我通过遵循rapidjson文件夹中的schemavalidator.cpp示例找到了答案。 我在这里提供我的案例的示例: https://github.com/faudard/rapidjson_scheme 我使用与示例相同的“CreateErrorMessages”。
您可以使用 validator.GetError() 获取缺失的关键词列表; 它将提供错误代码以及您可以从该错误代码获取数据的详细信息。 我尝试如下
typedef GenericValue<UTF8<>, CrtAllocator > ValueType;?????
if( validator.GetInvalidSchemaKeyword() == string("required"))
{
ValueType & error = validator.GetError();
StringBuffer sb;
Writer<StringBuffer>writer(sb);
error.Accept(writer);
cout << "payload " << sb.GetString() << endl;
Document doc;
doc.Parse(sb.GetString());
if(doc.HasParseError())
{
cout << "has parse error " << doc.GetParseError() << endl;
}
else
{
// Value & required = doc["required"];
// Value & missing = required["missing"];
Value & missing = (doc["required"])["missing"];
cout << "missing fields from the payload" << endl;
for(auto itr = missing.Begin();itr!=missing.End();itr++)
{
cout << itr->GetString() << endl;
}
}
}
您可以使用错误代码来尝试数据类型不匹配 我的例子如下
{
"class":10,
"name":"chand",
"marks":[10,21.3,80],
"percentage":23.89,
"address":
{
"street":"12",
"village":"abc",
"state":"sample state"
}
}
如果必填字段缺少错误代码,则错误代码为
{"required":{"missing:["name","class"],"errorCode":15,"instanceRef":"#","schemaRef":"#"}}
如果数据未匹配错误代码,则错误代码为
{"type":{"expected:["integer"],"actual":"string","errorCode":20,"instanceRef":"#/class","schemaRef":"#/properties/class"}}
我认为使用这个错误代码我们可以得到无效模式的详细解释
参考链接:https://github.com/Tencent/rapidjson/blob/master/example/schemavalidator/schemavalidator.cpp