Search code examples
c++schemarapidjson

how to make the rapidjson::SchemaValidator variable in the class


I have an class it is going to validate the json data with json schema

const char *ptr = R"(
    {
    "type":"object",
    "properties":{
    "name":{"type":"string"}
    },
    "required":["name"]
    }
    )";
const char *data = R"(
    {
    "name":"12"
    }
    )";
class Test {
   public:
    bool validate(Document &doc) {
        Document sdoc;
        sdoc.Parse(ptr);
        RAPIDJSON_ASSERT(!sdoc.HasParseError());
        SchemaDocument schema(sdoc);
        SchemaValidator validator(schema);
        if (doc.Accept(validator))
            return true;
        else
            return false;
    }
};

this code was working properly but in my requirement I no need to create the validator again and again when ever it is required,I feel if the validator is inside the class member then we can reduce the time

class Test {
    SchemaValidator validator;

   public:
    bool validate(Document &doc) {
        if (doc.Accept(validator))
            return true;
        else
            return false;
    }
};

can anybody please help how we can do for my requirement.


Solution

  • You need to hold both rapidjson::SchemaDocument and rapidjson::SchemaValidator as your member fields, because SchemaValidator keeps non-owning pointer to SchemaDocument. Sth like this:

    class Test2 {
    public:
        Test2()
            : _schema{[]() {
                rapidjson::Document sdoc;
                sdoc.Parse(ptr);
                if (sdoc.HasParseError()) {
                    throw std::runtime_error("Bad schema");
                }
                return rapidjson::SchemaDocument(sdoc);
            }()}
            , _validator{_schema} {}
        bool validate(rapidjson::Document &doc) {
            if (doc.Accept(_validator))
                return true;
            else
                return false;
        }
    
    private:
        rapidjson::SchemaDocument _schema;
        rapidjson::SchemaValidator _validator;
    };
    

    Then to be cleaner, you can make your class to accept std::string schema in the constructor

        Test2(std::string schema)
            : _schema{[schema]() {
                rapidjson::Document sdoc;
                sdoc.Parse(schema.c_str());
                if (sdoc.HasParseError()) {
                    throw std::runtime_error("Bad schema");
                }
                return rapidjson::SchemaDocument(sdoc);
            }()}
            , _validator{_schema} {}