daday001
daday001

Reputation: 101

rapidjson schema how to get the keyword from the error

I'm making a physical software and we deploy a json solution and I wanted to used json schema. So, when I had a wrong key typical looking a "length" in the schema and the user gives somethings wrong like "length2". I don't know how to get it with rapidjson actually, I obtained these results

Invalid schema: #/properties/TEST
Invalid keyword: required
Invalid document: #/TEST 

But I want an output like "length" key is missing in order to inform the user.

Imy test.json file:

{
    "$schema": "./schema.json", 
    "TEST": {
        "Length2": {
            "Value":20,
            "Unit":"mm"
        }
    } 
}

Edit following Ether comment my schema.json but this doesn't change my output see "Invalid schema"

{
    "type": "object",
    "required": ["TEST"],
    "properties": {
        "TEST": {
            "type": "object",
            "required": ["Length"],
            "properties": {
                    "Length":{
                        "type": "object",
                        "required": ["Value","Unit"],
                        "properties": {
                            "Value": {"type": "number"},
                            "Unit": {"type": "string"}
                    }       
                }         
            }
        }
    }
}

and my cpp code:

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

Upvotes: 0

Views: 662

Answers (3)

You can get the missing key words list by using validator.GetError(); It will give the error code with details from that error code you can fetch the data. I tried as follows

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

You can experiment on Data type missmatching aslo with errorcode My exampleas follows

{
   "class":10,
   "name":"chand",
    "marks":[10,21.3,80],
    "percentage":23.89,
    "address":
      {
            "street":"12",
            "village":"abc",
            "state":"sample state"
      }
}

Error code if requied fields are missing error code as

{"required":{"missing:["name","class"],"errorCode":15,"instanceRef":"#","schemaRef":"#"}}

Error code if data miss matching error code as

{"type":{"expected:["integer"],"actual":"string","errorCode":20,"instanceRef":"#/class","schemaRef":"#/properties/class"}}

I think using this error code we can get the detailed explanation for the invalid schema

reference link : https://github.com/Tencent/rapidjson/blob/master/example/schemavalidator/schemavalidator.cpp

Upvotes: 0

daday001
daday001

Reputation: 101

So I found my answer by following the schemavalidator.cpp example in rapidjson folder. I provide here the example in my case : https://github.com/faudard/rapidjson_scheme I use the "CreateErrorMessages" same to the example.

Upvotes: 0

Ether
Ether

Reputation: 53996

At /properties/TEST/properties you should have property names, not a schema. Perhaps you are missing the "Length" property to contain that subschema?

Upvotes: 0

Related Questions