The following scenario:
- There's a
general schema with a type definition.
- There's a
special schema with a type definition referring to the type definition from the general schema.
- There's an
entities schema referencing the type definition from special schema. It's initialized with provider which knows about both general and special schemas.
- There's a document that must conform to the
entities schema.
The code:
#include "rapidjson/schema.h"
#include <cstdio>
using namespace rapidjson;
constexpr const char general[] = R"(
{
"vector": {
"type": ["array"],
"items": {
"type": "number"
},
"minItems": 3,
"maxItems": 3
}
}
)";
constexpr const char special[] = R"(
{
"entity_data": {
"type": "object",
"properties": {
"origin": {
"$ref": "general.json#/vector"
}
},
"additionalProperties": false
}
}
)";
constexpr const char entities[] = R"(
{
"type": "object",
"additionalProperties": {
"$ref": "special.json#/entity_data"
}
}
)";
class DefinitionsProvider : public IRemoteSchemaDocumentProvider
{
public:
DefinitionsProvider(const Document& generalDocument, const Document& specialDocument): _general(generalDocument), _special(specialDocument) {}
const SchemaDocument* GetRemoteDocument(const char* uri, SizeType length) {
if (strncmp(uri, "special.json", length) == 0)
{
return &_special;
}
return &_general;
}
private:
SchemaDocument _general;
SchemaDocument _special;
};
constexpr const char documentText[] = R"(
{
"entity1": {
"origin": [0, 0, 0]
},
"entity2": {
"origin": "string"
}
}
)";
int main()
{
ParseResult parseResult;
Document generalSchemaDocument;
generalSchemaDocument.Parse(general);
parseResult = generalSchemaDocument;
if (!parseResult)
{
fprintf(stderr, "Error reading general schema\n");
return 1;
}
Document specialSchemaDocument;
specialSchemaDocument.Parse(special);
parseResult = specialSchemaDocument;
if (!parseResult)
{
fprintf(stderr, "Error reading special schema\n");
return 1;
}
DefinitionsProvider provider(generalSchemaDocument, specialSchemaDocument);
Document schemaDocument;
schemaDocument.Parse(entities);
parseResult = schemaDocument;
if (!parseResult)
{
fprintf(stderr, "Error reading entities schema\n");
return 1;
}
SchemaDocument schema(schemaDocument, 0, 0, &provider);
Document document;
document.Parse(documentText);
parseResult = document;
if (!parseResult)
{
fprintf(stderr, "Error reading document\n");
return 1;
}
SchemaValidator validator(schema);
if (!document.Accept(validator))
{
fprintf(stderr, "Bad document\n");
}
else
{
printf("Good document\n");
}
return 0;
}
This prints "Good document" despite "origin" in "entity2" being a string, thus not matching the "vector" type.
This does validation using the "special" schema though (e.g. if I add any other property to any entity - this is prohibited due to "additionalProperties": false).
The following scenario:
generalschema with a type definition.specialschema with a type definition referring to the type definition from thegeneralschema.entitiesschema referencing the type definition fromspecialschema. It's initialized with provider which knows about bothgeneralandspecialschemas.entitiesschema.The code:
This prints "Good document" despite
"origin"in"entity2"being a string, thus not matching the"vector"type.This does validation using the
"special"schema though (e.g. if I add any other property to any entity - this is prohibited due to"additionalProperties": false).