4

Data:

{
   "languages": ['en', 'ch'],
   "file": {
      "en": "file1",
      "ch": "file2"
    }
}

How to define a schema that verifies name of keys in file property by "languages" property?

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "description": "",
  "type": "object",
  "properties": {
    "languages": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "file": {
      "type": "object",
      "properties": ????
    }
}

2 Answers 2

3

You can define additional data constrains using custom keywords, that are supported by some validators, e.g. Ajv (I am the author):

var Ajv = require('ajv');
var ajv = new Ajv;
ajv.addKeyword('validateLocales', {
    type: 'object',
    compile: function(schema) {
        return function(data, dataPath, parentData) {
            for (var prop in data) {
                if (parentData[schema.localesProperty].indexOf(prop) == -1) {
                    return false;
                }
            }
            return true;
        }
    },
    metaSchema: {
        type: 'object',
        properties: {
            localesProperty: { type: 'string' }
        },
        additionalProperties: false
    }
});

var schema = {
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "languages": {
      "type": "array",
      "items": { "type": "string" }
    },
    "file": {
      "type": "object",
      "validateLocales": {
          "localesProperty": "languages"
      },
      "additionalProperties": { "type": "string" }
    }
  }
};

var data = {
   "languages": ['en', 'ch'],
   "file": {
      "en": "file1",
      "ch": "file2"
    }
};

var validate = ajv.compile(schema);
console.log(validate(data));

See https://runkit.com/esp/57d9d419646b97130082de34

Sign up to request clarification or add additional context in comments.

12 Comments

What if i need to put my file 2 or more levels deep? e.g. gist.github.com/Truedrog/201c34a1f9b119d1416eeff485b8c3cc
also in compilation function schema.localesProperty equales 'languages', not they key of my languages array so parentData[schema.localesProperty].indexOf(prop) == -1 couldn't check because of the undefined error.
Well, i workarounded my problem with the root data argument. Could it be done with $data reference from v5 proposal?
Custom keywords in Ajv have some support for $data reference
Ok. Got it. But should i rely on root data which passed to compilation function in my case (deep nested property)?
|
-1

It is definitely not possible to express such constraint with json schema.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.