JSON Schema conditional: require and not require












0














question 1.I'm trying to implement this condition: if a special property exist another property require but if it is not exist another one not require
question 2.in json schema can we use not in dependencies?
Here is a sample schema



var schema = {
"properties": {
"smaller": {
"type": "number"
},
"larger": { "type": "number" },
"medium":{'type':'string'},
"bulky":{'type':'string'}
},
require:['smaller','larger'],
additionalProperties:false
};


if "medium" then require "bulky" else not require bulky.
here "not require" means that if "medium" dont exist then bulky " must not be present"










share|improve this question
























  • It'd help if you mention for which draft version of JSON SCHEMA it'd be shaped and provide sample JSON doc.
    – PsychoFish
    Nov 21 at 0:42










  • for draft-6 - here "not require" means that if "medium" dont exist then bulky " must not be present"
    – h.ataie
    Nov 21 at 8:36










  • See updated answer. If I understood your update correctly, this might answer your question.
    – PsychoFish
    Nov 21 at 16:37
















0














question 1.I'm trying to implement this condition: if a special property exist another property require but if it is not exist another one not require
question 2.in json schema can we use not in dependencies?
Here is a sample schema



var schema = {
"properties": {
"smaller": {
"type": "number"
},
"larger": { "type": "number" },
"medium":{'type':'string'},
"bulky":{'type':'string'}
},
require:['smaller','larger'],
additionalProperties:false
};


if "medium" then require "bulky" else not require bulky.
here "not require" means that if "medium" dont exist then bulky " must not be present"










share|improve this question
























  • It'd help if you mention for which draft version of JSON SCHEMA it'd be shaped and provide sample JSON doc.
    – PsychoFish
    Nov 21 at 0:42










  • for draft-6 - here "not require" means that if "medium" dont exist then bulky " must not be present"
    – h.ataie
    Nov 21 at 8:36










  • See updated answer. If I understood your update correctly, this might answer your question.
    – PsychoFish
    Nov 21 at 16:37














0












0








0







question 1.I'm trying to implement this condition: if a special property exist another property require but if it is not exist another one not require
question 2.in json schema can we use not in dependencies?
Here is a sample schema



var schema = {
"properties": {
"smaller": {
"type": "number"
},
"larger": { "type": "number" },
"medium":{'type':'string'},
"bulky":{'type':'string'}
},
require:['smaller','larger'],
additionalProperties:false
};


if "medium" then require "bulky" else not require bulky.
here "not require" means that if "medium" dont exist then bulky " must not be present"










share|improve this question















question 1.I'm trying to implement this condition: if a special property exist another property require but if it is not exist another one not require
question 2.in json schema can we use not in dependencies?
Here is a sample schema



var schema = {
"properties": {
"smaller": {
"type": "number"
},
"larger": { "type": "number" },
"medium":{'type':'string'},
"bulky":{'type':'string'}
},
require:['smaller','larger'],
additionalProperties:false
};


if "medium" then require "bulky" else not require bulky.
here "not require" means that if "medium" dont exist then bulky " must not be present"







jsonschema






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 at 8:38

























asked Nov 20 at 17:36









h.ataie

33




33












  • It'd help if you mention for which draft version of JSON SCHEMA it'd be shaped and provide sample JSON doc.
    – PsychoFish
    Nov 21 at 0:42










  • for draft-6 - here "not require" means that if "medium" dont exist then bulky " must not be present"
    – h.ataie
    Nov 21 at 8:36










  • See updated answer. If I understood your update correctly, this might answer your question.
    – PsychoFish
    Nov 21 at 16:37


















  • It'd help if you mention for which draft version of JSON SCHEMA it'd be shaped and provide sample JSON doc.
    – PsychoFish
    Nov 21 at 0:42










  • for draft-6 - here "not require" means that if "medium" dont exist then bulky " must not be present"
    – h.ataie
    Nov 21 at 8:36










  • See updated answer. If I understood your update correctly, this might answer your question.
    – PsychoFish
    Nov 21 at 16:37
















It'd help if you mention for which draft version of JSON SCHEMA it'd be shaped and provide sample JSON doc.
– PsychoFish
Nov 21 at 0:42




It'd help if you mention for which draft version of JSON SCHEMA it'd be shaped and provide sample JSON doc.
– PsychoFish
Nov 21 at 0:42












for draft-6 - here "not require" means that if "medium" dont exist then bulky " must not be present"
– h.ataie
Nov 21 at 8:36




for draft-6 - here "not require" means that if "medium" dont exist then bulky " must not be present"
– h.ataie
Nov 21 at 8:36












See updated answer. If I understood your update correctly, this might answer your question.
– PsychoFish
Nov 21 at 16:37




See updated answer. If I understood your update correctly, this might answer your question.
– PsychoFish
Nov 21 at 16:37












2 Answers
2






active

oldest

votes


















3














There are several ways to achieve required effect even not using JSON Schema draft-07 if-then-else.



logical operator and implication (draft-04 and above)



A logical implication here: if "medium" present then "bulky" is required can be translated to "medium" not present OR "bulky" is "required" (the latter implicates "medium" is present) which can be further elaborated to "medium" not required OR "bulky" is "required" (since if "medium" is present, it will satisfy condition of being required). See below schema:



"properties": {
"smaller": {"type": "number"},
"larger": { "type": "number" },
"medium":{"type":"string"},
"bulky":{"type":"string"}
},
"required":["smaller","larger"],
"anyOf" : [
{
"not" : { "required" : ["medium"] }
},
{
"required" : ["bulky"]
}
],
"additionalProperties" : false


Check here for reference:



JSON schema - valid if object does *not* contain a particular property



http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.7



"anyOf" - logical OR, "oneOf" - XOR, "allOf" - AND, "not" - negation, yet pay attention to spec:




An instance is valid against this keyword if it fails to validate successfully against the schema defined by this keyword.




draft-06 - dependencies + propertyNames



Most obvious. I am not sure if you excluded this one in your question, so putting here just in case. Please note, that instead of "additionalProperties", if you wan't simply to limit valid keys, "propertyNames" could be used (and is actually what it was added for).



"properties": {
"smaller": {"type": "number"},
"larger": { "type": "number" },
"medium":{"type":"string"},
"bulky":{"type":"string"}
},
"required":["smaller","larger"],
"dependencies" : {
"medium" : ["bulky"]
},
"propertyNames" : {
"enum" : [
"smaller",
"larger",
"medium",
"bulky"
]
}


Check here for reference: http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.5.7



Update



After clarification in comment:




for draft-6 - here "not require" means that if "medium" dont exist then bulky " must not be present"




"must not" means preventing bulky being present.



I will rephrase your condition:



1. if "medium" exists "bulky" must be present -> both keys must be present at the same time



2. if "medium" does not exist "bulky" must not be present as well -> both keys must not be present at the same time



Can "bulky" exist and "medium" does not exist?



No. See 2. And vice versa (see 1.). Boolean equality (complementary to logical XOR).



Thus if "bulky" exists - it means "medium" must be always there... It implies that both are required or both must not be required (or even allowed).



Since it's draft-06, you can use also "propertyNames" for defining allowed property names (kind of shortcut to this logic).



logical operator and implication (draft-06 and above)



The proper logical operation translated to JSOn Schema would look like:



"oneOf" : [
{ "required" : ["medium","bulky"] }, <== this schema is satisfied if both keys appear in validated instance
{
"allOf" : [ <== !medium ^ !bulky - due to how "not" works in schema context
{"not" : { "required" : ["medium"] } },
{"not" : { "required" : ["bulky"] } },
]
}
]


An XOR - EITHER (both required) OR (medium not required AND bulky not required).



Please note I am not doing "not" : { "required" : ["medium","bulky"] } as when just one of those keys is present, "required" schema would fail which would mean "not" would return successfull validation result. One needs to rephrase it using de Morgans laws:



"oneOf" : [
{ "required" : ["medium","bulky"] },
{
"not" : { <=== !medium ^ !bulky = !(medium v bulky)
"anyOf" : [
{ "required" : ["medium"] },
{ "required" : ["bulky"] },
]
}
}
]


However using "propertyNames" will also do the trick.
See following schema:



{
"$schema": "http://json-schema.org/draft-06/schema#",
"properties": {
"smaller": {"type": "number"},
"larger": { "type": "number" },
"medium":{"type":"string"},
"bulky":{"type":"string"}
},
"required":["smaller","larger"],
"anyOf" : [
{
"required" : ["medium","bulky"]
},
{
"propertyNames" : {
"enum" : [
"smaller",
"larger"
]
},
}
],
"examples" : [
{
"smaller" : 1,
"larger" : 2,


},
{
"smaller" : 1,
"larger" : 2,
"bulky" : "test",
"medium" : ""
},
{
"smaller" : 1,
"larger" : 2,

"medium" : ""
},
{
"smaller" : 1,
"larger" : 2,
"bulky" : "test",

},
]
}


Does it answer your question?






share|improve this answer



















  • 1




    tanx very much.its working
    – h.ataie
    Nov 22 at 4:50










  • Glad I could help. If I may suggest something for the future: try to write down your conditions in terms of Boolean expressions. Properly describing topic often reveals solution straight away.
    – PsychoFish
    Nov 23 at 15:33



















1














JSON Schema Draft-07 has included these new keywords if, then and else which allow you to have conditional schemas.



In this example:




  • Only the foo property is required

  • However if foo is set to "bar" then the bar property also becomes required





var ajv = new Ajv({
allErrors: true
});

var schema = {
"properties": {
"foo": {
"type": "string"
},
"bar": {
"type": "string"
},

},
"required": ["foo"],
"if": {
"properties": {
"foo": {
"enum": ["bar"]
}
}
},
"then": {
"required": ["bar"]
}
}

var validate = ajv.compile(schema);

test({
"foo": "bar",
"bar": "baz"
}); // VALID

test({
"foo": "xyz"
}); // VALID

test({
"foo": "bar",
}); // NOT VALID


function test(data) {
var valid = validate(data);
if (valid) console.log('VALID', data);
else console.log('NOT VALID', data);
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.5.5/ajv.min.js"></script>





Hopefully this makes sense and you can adapt your code accordingly.



PS: in your schema you have the require property which I'm not sure is a valid JSON Schema keyword. You probably meant required instead.






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53398519%2fjson-schema-conditional-require-and-not-require%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    There are several ways to achieve required effect even not using JSON Schema draft-07 if-then-else.



    logical operator and implication (draft-04 and above)



    A logical implication here: if "medium" present then "bulky" is required can be translated to "medium" not present OR "bulky" is "required" (the latter implicates "medium" is present) which can be further elaborated to "medium" not required OR "bulky" is "required" (since if "medium" is present, it will satisfy condition of being required). See below schema:



    "properties": {
    "smaller": {"type": "number"},
    "larger": { "type": "number" },
    "medium":{"type":"string"},
    "bulky":{"type":"string"}
    },
    "required":["smaller","larger"],
    "anyOf" : [
    {
    "not" : { "required" : ["medium"] }
    },
    {
    "required" : ["bulky"]
    }
    ],
    "additionalProperties" : false


    Check here for reference:



    JSON schema - valid if object does *not* contain a particular property



    http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.7



    "anyOf" - logical OR, "oneOf" - XOR, "allOf" - AND, "not" - negation, yet pay attention to spec:




    An instance is valid against this keyword if it fails to validate successfully against the schema defined by this keyword.




    draft-06 - dependencies + propertyNames



    Most obvious. I am not sure if you excluded this one in your question, so putting here just in case. Please note, that instead of "additionalProperties", if you wan't simply to limit valid keys, "propertyNames" could be used (and is actually what it was added for).



    "properties": {
    "smaller": {"type": "number"},
    "larger": { "type": "number" },
    "medium":{"type":"string"},
    "bulky":{"type":"string"}
    },
    "required":["smaller","larger"],
    "dependencies" : {
    "medium" : ["bulky"]
    },
    "propertyNames" : {
    "enum" : [
    "smaller",
    "larger",
    "medium",
    "bulky"
    ]
    }


    Check here for reference: http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.5.7



    Update



    After clarification in comment:




    for draft-6 - here "not require" means that if "medium" dont exist then bulky " must not be present"




    "must not" means preventing bulky being present.



    I will rephrase your condition:



    1. if "medium" exists "bulky" must be present -> both keys must be present at the same time



    2. if "medium" does not exist "bulky" must not be present as well -> both keys must not be present at the same time



    Can "bulky" exist and "medium" does not exist?



    No. See 2. And vice versa (see 1.). Boolean equality (complementary to logical XOR).



    Thus if "bulky" exists - it means "medium" must be always there... It implies that both are required or both must not be required (or even allowed).



    Since it's draft-06, you can use also "propertyNames" for defining allowed property names (kind of shortcut to this logic).



    logical operator and implication (draft-06 and above)



    The proper logical operation translated to JSOn Schema would look like:



    "oneOf" : [
    { "required" : ["medium","bulky"] }, <== this schema is satisfied if both keys appear in validated instance
    {
    "allOf" : [ <== !medium ^ !bulky - due to how "not" works in schema context
    {"not" : { "required" : ["medium"] } },
    {"not" : { "required" : ["bulky"] } },
    ]
    }
    ]


    An XOR - EITHER (both required) OR (medium not required AND bulky not required).



    Please note I am not doing "not" : { "required" : ["medium","bulky"] } as when just one of those keys is present, "required" schema would fail which would mean "not" would return successfull validation result. One needs to rephrase it using de Morgans laws:



    "oneOf" : [
    { "required" : ["medium","bulky"] },
    {
    "not" : { <=== !medium ^ !bulky = !(medium v bulky)
    "anyOf" : [
    { "required" : ["medium"] },
    { "required" : ["bulky"] },
    ]
    }
    }
    ]


    However using "propertyNames" will also do the trick.
    See following schema:



    {
    "$schema": "http://json-schema.org/draft-06/schema#",
    "properties": {
    "smaller": {"type": "number"},
    "larger": { "type": "number" },
    "medium":{"type":"string"},
    "bulky":{"type":"string"}
    },
    "required":["smaller","larger"],
    "anyOf" : [
    {
    "required" : ["medium","bulky"]
    },
    {
    "propertyNames" : {
    "enum" : [
    "smaller",
    "larger"
    ]
    },
    }
    ],
    "examples" : [
    {
    "smaller" : 1,
    "larger" : 2,


    },
    {
    "smaller" : 1,
    "larger" : 2,
    "bulky" : "test",
    "medium" : ""
    },
    {
    "smaller" : 1,
    "larger" : 2,

    "medium" : ""
    },
    {
    "smaller" : 1,
    "larger" : 2,
    "bulky" : "test",

    },
    ]
    }


    Does it answer your question?






    share|improve this answer



















    • 1




      tanx very much.its working
      – h.ataie
      Nov 22 at 4:50










    • Glad I could help. If I may suggest something for the future: try to write down your conditions in terms of Boolean expressions. Properly describing topic often reveals solution straight away.
      – PsychoFish
      Nov 23 at 15:33
















    3














    There are several ways to achieve required effect even not using JSON Schema draft-07 if-then-else.



    logical operator and implication (draft-04 and above)



    A logical implication here: if "medium" present then "bulky" is required can be translated to "medium" not present OR "bulky" is "required" (the latter implicates "medium" is present) which can be further elaborated to "medium" not required OR "bulky" is "required" (since if "medium" is present, it will satisfy condition of being required). See below schema:



    "properties": {
    "smaller": {"type": "number"},
    "larger": { "type": "number" },
    "medium":{"type":"string"},
    "bulky":{"type":"string"}
    },
    "required":["smaller","larger"],
    "anyOf" : [
    {
    "not" : { "required" : ["medium"] }
    },
    {
    "required" : ["bulky"]
    }
    ],
    "additionalProperties" : false


    Check here for reference:



    JSON schema - valid if object does *not* contain a particular property



    http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.7



    "anyOf" - logical OR, "oneOf" - XOR, "allOf" - AND, "not" - negation, yet pay attention to spec:




    An instance is valid against this keyword if it fails to validate successfully against the schema defined by this keyword.




    draft-06 - dependencies + propertyNames



    Most obvious. I am not sure if you excluded this one in your question, so putting here just in case. Please note, that instead of "additionalProperties", if you wan't simply to limit valid keys, "propertyNames" could be used (and is actually what it was added for).



    "properties": {
    "smaller": {"type": "number"},
    "larger": { "type": "number" },
    "medium":{"type":"string"},
    "bulky":{"type":"string"}
    },
    "required":["smaller","larger"],
    "dependencies" : {
    "medium" : ["bulky"]
    },
    "propertyNames" : {
    "enum" : [
    "smaller",
    "larger",
    "medium",
    "bulky"
    ]
    }


    Check here for reference: http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.5.7



    Update



    After clarification in comment:




    for draft-6 - here "not require" means that if "medium" dont exist then bulky " must not be present"




    "must not" means preventing bulky being present.



    I will rephrase your condition:



    1. if "medium" exists "bulky" must be present -> both keys must be present at the same time



    2. if "medium" does not exist "bulky" must not be present as well -> both keys must not be present at the same time



    Can "bulky" exist and "medium" does not exist?



    No. See 2. And vice versa (see 1.). Boolean equality (complementary to logical XOR).



    Thus if "bulky" exists - it means "medium" must be always there... It implies that both are required or both must not be required (or even allowed).



    Since it's draft-06, you can use also "propertyNames" for defining allowed property names (kind of shortcut to this logic).



    logical operator and implication (draft-06 and above)



    The proper logical operation translated to JSOn Schema would look like:



    "oneOf" : [
    { "required" : ["medium","bulky"] }, <== this schema is satisfied if both keys appear in validated instance
    {
    "allOf" : [ <== !medium ^ !bulky - due to how "not" works in schema context
    {"not" : { "required" : ["medium"] } },
    {"not" : { "required" : ["bulky"] } },
    ]
    }
    ]


    An XOR - EITHER (both required) OR (medium not required AND bulky not required).



    Please note I am not doing "not" : { "required" : ["medium","bulky"] } as when just one of those keys is present, "required" schema would fail which would mean "not" would return successfull validation result. One needs to rephrase it using de Morgans laws:



    "oneOf" : [
    { "required" : ["medium","bulky"] },
    {
    "not" : { <=== !medium ^ !bulky = !(medium v bulky)
    "anyOf" : [
    { "required" : ["medium"] },
    { "required" : ["bulky"] },
    ]
    }
    }
    ]


    However using "propertyNames" will also do the trick.
    See following schema:



    {
    "$schema": "http://json-schema.org/draft-06/schema#",
    "properties": {
    "smaller": {"type": "number"},
    "larger": { "type": "number" },
    "medium":{"type":"string"},
    "bulky":{"type":"string"}
    },
    "required":["smaller","larger"],
    "anyOf" : [
    {
    "required" : ["medium","bulky"]
    },
    {
    "propertyNames" : {
    "enum" : [
    "smaller",
    "larger"
    ]
    },
    }
    ],
    "examples" : [
    {
    "smaller" : 1,
    "larger" : 2,


    },
    {
    "smaller" : 1,
    "larger" : 2,
    "bulky" : "test",
    "medium" : ""
    },
    {
    "smaller" : 1,
    "larger" : 2,

    "medium" : ""
    },
    {
    "smaller" : 1,
    "larger" : 2,
    "bulky" : "test",

    },
    ]
    }


    Does it answer your question?






    share|improve this answer



















    • 1




      tanx very much.its working
      – h.ataie
      Nov 22 at 4:50










    • Glad I could help. If I may suggest something for the future: try to write down your conditions in terms of Boolean expressions. Properly describing topic often reveals solution straight away.
      – PsychoFish
      Nov 23 at 15:33














    3












    3








    3






    There are several ways to achieve required effect even not using JSON Schema draft-07 if-then-else.



    logical operator and implication (draft-04 and above)



    A logical implication here: if "medium" present then "bulky" is required can be translated to "medium" not present OR "bulky" is "required" (the latter implicates "medium" is present) which can be further elaborated to "medium" not required OR "bulky" is "required" (since if "medium" is present, it will satisfy condition of being required). See below schema:



    "properties": {
    "smaller": {"type": "number"},
    "larger": { "type": "number" },
    "medium":{"type":"string"},
    "bulky":{"type":"string"}
    },
    "required":["smaller","larger"],
    "anyOf" : [
    {
    "not" : { "required" : ["medium"] }
    },
    {
    "required" : ["bulky"]
    }
    ],
    "additionalProperties" : false


    Check here for reference:



    JSON schema - valid if object does *not* contain a particular property



    http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.7



    "anyOf" - logical OR, "oneOf" - XOR, "allOf" - AND, "not" - negation, yet pay attention to spec:




    An instance is valid against this keyword if it fails to validate successfully against the schema defined by this keyword.




    draft-06 - dependencies + propertyNames



    Most obvious. I am not sure if you excluded this one in your question, so putting here just in case. Please note, that instead of "additionalProperties", if you wan't simply to limit valid keys, "propertyNames" could be used (and is actually what it was added for).



    "properties": {
    "smaller": {"type": "number"},
    "larger": { "type": "number" },
    "medium":{"type":"string"},
    "bulky":{"type":"string"}
    },
    "required":["smaller","larger"],
    "dependencies" : {
    "medium" : ["bulky"]
    },
    "propertyNames" : {
    "enum" : [
    "smaller",
    "larger",
    "medium",
    "bulky"
    ]
    }


    Check here for reference: http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.5.7



    Update



    After clarification in comment:




    for draft-6 - here "not require" means that if "medium" dont exist then bulky " must not be present"




    "must not" means preventing bulky being present.



    I will rephrase your condition:



    1. if "medium" exists "bulky" must be present -> both keys must be present at the same time



    2. if "medium" does not exist "bulky" must not be present as well -> both keys must not be present at the same time



    Can "bulky" exist and "medium" does not exist?



    No. See 2. And vice versa (see 1.). Boolean equality (complementary to logical XOR).



    Thus if "bulky" exists - it means "medium" must be always there... It implies that both are required or both must not be required (or even allowed).



    Since it's draft-06, you can use also "propertyNames" for defining allowed property names (kind of shortcut to this logic).



    logical operator and implication (draft-06 and above)



    The proper logical operation translated to JSOn Schema would look like:



    "oneOf" : [
    { "required" : ["medium","bulky"] }, <== this schema is satisfied if both keys appear in validated instance
    {
    "allOf" : [ <== !medium ^ !bulky - due to how "not" works in schema context
    {"not" : { "required" : ["medium"] } },
    {"not" : { "required" : ["bulky"] } },
    ]
    }
    ]


    An XOR - EITHER (both required) OR (medium not required AND bulky not required).



    Please note I am not doing "not" : { "required" : ["medium","bulky"] } as when just one of those keys is present, "required" schema would fail which would mean "not" would return successfull validation result. One needs to rephrase it using de Morgans laws:



    "oneOf" : [
    { "required" : ["medium","bulky"] },
    {
    "not" : { <=== !medium ^ !bulky = !(medium v bulky)
    "anyOf" : [
    { "required" : ["medium"] },
    { "required" : ["bulky"] },
    ]
    }
    }
    ]


    However using "propertyNames" will also do the trick.
    See following schema:



    {
    "$schema": "http://json-schema.org/draft-06/schema#",
    "properties": {
    "smaller": {"type": "number"},
    "larger": { "type": "number" },
    "medium":{"type":"string"},
    "bulky":{"type":"string"}
    },
    "required":["smaller","larger"],
    "anyOf" : [
    {
    "required" : ["medium","bulky"]
    },
    {
    "propertyNames" : {
    "enum" : [
    "smaller",
    "larger"
    ]
    },
    }
    ],
    "examples" : [
    {
    "smaller" : 1,
    "larger" : 2,


    },
    {
    "smaller" : 1,
    "larger" : 2,
    "bulky" : "test",
    "medium" : ""
    },
    {
    "smaller" : 1,
    "larger" : 2,

    "medium" : ""
    },
    {
    "smaller" : 1,
    "larger" : 2,
    "bulky" : "test",

    },
    ]
    }


    Does it answer your question?






    share|improve this answer














    There are several ways to achieve required effect even not using JSON Schema draft-07 if-then-else.



    logical operator and implication (draft-04 and above)



    A logical implication here: if "medium" present then "bulky" is required can be translated to "medium" not present OR "bulky" is "required" (the latter implicates "medium" is present) which can be further elaborated to "medium" not required OR "bulky" is "required" (since if "medium" is present, it will satisfy condition of being required). See below schema:



    "properties": {
    "smaller": {"type": "number"},
    "larger": { "type": "number" },
    "medium":{"type":"string"},
    "bulky":{"type":"string"}
    },
    "required":["smaller","larger"],
    "anyOf" : [
    {
    "not" : { "required" : ["medium"] }
    },
    {
    "required" : ["bulky"]
    }
    ],
    "additionalProperties" : false


    Check here for reference:



    JSON schema - valid if object does *not* contain a particular property



    http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.7



    "anyOf" - logical OR, "oneOf" - XOR, "allOf" - AND, "not" - negation, yet pay attention to spec:




    An instance is valid against this keyword if it fails to validate successfully against the schema defined by this keyword.




    draft-06 - dependencies + propertyNames



    Most obvious. I am not sure if you excluded this one in your question, so putting here just in case. Please note, that instead of "additionalProperties", if you wan't simply to limit valid keys, "propertyNames" could be used (and is actually what it was added for).



    "properties": {
    "smaller": {"type": "number"},
    "larger": { "type": "number" },
    "medium":{"type":"string"},
    "bulky":{"type":"string"}
    },
    "required":["smaller","larger"],
    "dependencies" : {
    "medium" : ["bulky"]
    },
    "propertyNames" : {
    "enum" : [
    "smaller",
    "larger",
    "medium",
    "bulky"
    ]
    }


    Check here for reference: http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.5.7



    Update



    After clarification in comment:




    for draft-6 - here "not require" means that if "medium" dont exist then bulky " must not be present"




    "must not" means preventing bulky being present.



    I will rephrase your condition:



    1. if "medium" exists "bulky" must be present -> both keys must be present at the same time



    2. if "medium" does not exist "bulky" must not be present as well -> both keys must not be present at the same time



    Can "bulky" exist and "medium" does not exist?



    No. See 2. And vice versa (see 1.). Boolean equality (complementary to logical XOR).



    Thus if "bulky" exists - it means "medium" must be always there... It implies that both are required or both must not be required (or even allowed).



    Since it's draft-06, you can use also "propertyNames" for defining allowed property names (kind of shortcut to this logic).



    logical operator and implication (draft-06 and above)



    The proper logical operation translated to JSOn Schema would look like:



    "oneOf" : [
    { "required" : ["medium","bulky"] }, <== this schema is satisfied if both keys appear in validated instance
    {
    "allOf" : [ <== !medium ^ !bulky - due to how "not" works in schema context
    {"not" : { "required" : ["medium"] } },
    {"not" : { "required" : ["bulky"] } },
    ]
    }
    ]


    An XOR - EITHER (both required) OR (medium not required AND bulky not required).



    Please note I am not doing "not" : { "required" : ["medium","bulky"] } as when just one of those keys is present, "required" schema would fail which would mean "not" would return successfull validation result. One needs to rephrase it using de Morgans laws:



    "oneOf" : [
    { "required" : ["medium","bulky"] },
    {
    "not" : { <=== !medium ^ !bulky = !(medium v bulky)
    "anyOf" : [
    { "required" : ["medium"] },
    { "required" : ["bulky"] },
    ]
    }
    }
    ]


    However using "propertyNames" will also do the trick.
    See following schema:



    {
    "$schema": "http://json-schema.org/draft-06/schema#",
    "properties": {
    "smaller": {"type": "number"},
    "larger": { "type": "number" },
    "medium":{"type":"string"},
    "bulky":{"type":"string"}
    },
    "required":["smaller","larger"],
    "anyOf" : [
    {
    "required" : ["medium","bulky"]
    },
    {
    "propertyNames" : {
    "enum" : [
    "smaller",
    "larger"
    ]
    },
    }
    ],
    "examples" : [
    {
    "smaller" : 1,
    "larger" : 2,


    },
    {
    "smaller" : 1,
    "larger" : 2,
    "bulky" : "test",
    "medium" : ""
    },
    {
    "smaller" : 1,
    "larger" : 2,

    "medium" : ""
    },
    {
    "smaller" : 1,
    "larger" : 2,
    "bulky" : "test",

    },
    ]
    }


    Does it answer your question?







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 21 at 16:59

























    answered Nov 21 at 1:11









    PsychoFish

    82199




    82199








    • 1




      tanx very much.its working
      – h.ataie
      Nov 22 at 4:50










    • Glad I could help. If I may suggest something for the future: try to write down your conditions in terms of Boolean expressions. Properly describing topic often reveals solution straight away.
      – PsychoFish
      Nov 23 at 15:33














    • 1




      tanx very much.its working
      – h.ataie
      Nov 22 at 4:50










    • Glad I could help. If I may suggest something for the future: try to write down your conditions in terms of Boolean expressions. Properly describing topic often reveals solution straight away.
      – PsychoFish
      Nov 23 at 15:33








    1




    1




    tanx very much.its working
    – h.ataie
    Nov 22 at 4:50




    tanx very much.its working
    – h.ataie
    Nov 22 at 4:50












    Glad I could help. If I may suggest something for the future: try to write down your conditions in terms of Boolean expressions. Properly describing topic often reveals solution straight away.
    – PsychoFish
    Nov 23 at 15:33




    Glad I could help. If I may suggest something for the future: try to write down your conditions in terms of Boolean expressions. Properly describing topic often reveals solution straight away.
    – PsychoFish
    Nov 23 at 15:33













    1














    JSON Schema Draft-07 has included these new keywords if, then and else which allow you to have conditional schemas.



    In this example:




    • Only the foo property is required

    • However if foo is set to "bar" then the bar property also becomes required





    var ajv = new Ajv({
    allErrors: true
    });

    var schema = {
    "properties": {
    "foo": {
    "type": "string"
    },
    "bar": {
    "type": "string"
    },

    },
    "required": ["foo"],
    "if": {
    "properties": {
    "foo": {
    "enum": ["bar"]
    }
    }
    },
    "then": {
    "required": ["bar"]
    }
    }

    var validate = ajv.compile(schema);

    test({
    "foo": "bar",
    "bar": "baz"
    }); // VALID

    test({
    "foo": "xyz"
    }); // VALID

    test({
    "foo": "bar",
    }); // NOT VALID


    function test(data) {
    var valid = validate(data);
    if (valid) console.log('VALID', data);
    else console.log('NOT VALID', data);
    }

    <script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.5.5/ajv.min.js"></script>





    Hopefully this makes sense and you can adapt your code accordingly.



    PS: in your schema you have the require property which I'm not sure is a valid JSON Schema keyword. You probably meant required instead.






    share|improve this answer


























      1














      JSON Schema Draft-07 has included these new keywords if, then and else which allow you to have conditional schemas.



      In this example:




      • Only the foo property is required

      • However if foo is set to "bar" then the bar property also becomes required





      var ajv = new Ajv({
      allErrors: true
      });

      var schema = {
      "properties": {
      "foo": {
      "type": "string"
      },
      "bar": {
      "type": "string"
      },

      },
      "required": ["foo"],
      "if": {
      "properties": {
      "foo": {
      "enum": ["bar"]
      }
      }
      },
      "then": {
      "required": ["bar"]
      }
      }

      var validate = ajv.compile(schema);

      test({
      "foo": "bar",
      "bar": "baz"
      }); // VALID

      test({
      "foo": "xyz"
      }); // VALID

      test({
      "foo": "bar",
      }); // NOT VALID


      function test(data) {
      var valid = validate(data);
      if (valid) console.log('VALID', data);
      else console.log('NOT VALID', data);
      }

      <script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.5.5/ajv.min.js"></script>





      Hopefully this makes sense and you can adapt your code accordingly.



      PS: in your schema you have the require property which I'm not sure is a valid JSON Schema keyword. You probably meant required instead.






      share|improve this answer
























        1












        1








        1






        JSON Schema Draft-07 has included these new keywords if, then and else which allow you to have conditional schemas.



        In this example:




        • Only the foo property is required

        • However if foo is set to "bar" then the bar property also becomes required





        var ajv = new Ajv({
        allErrors: true
        });

        var schema = {
        "properties": {
        "foo": {
        "type": "string"
        },
        "bar": {
        "type": "string"
        },

        },
        "required": ["foo"],
        "if": {
        "properties": {
        "foo": {
        "enum": ["bar"]
        }
        }
        },
        "then": {
        "required": ["bar"]
        }
        }

        var validate = ajv.compile(schema);

        test({
        "foo": "bar",
        "bar": "baz"
        }); // VALID

        test({
        "foo": "xyz"
        }); // VALID

        test({
        "foo": "bar",
        }); // NOT VALID


        function test(data) {
        var valid = validate(data);
        if (valid) console.log('VALID', data);
        else console.log('NOT VALID', data);
        }

        <script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.5.5/ajv.min.js"></script>





        Hopefully this makes sense and you can adapt your code accordingly.



        PS: in your schema you have the require property which I'm not sure is a valid JSON Schema keyword. You probably meant required instead.






        share|improve this answer












        JSON Schema Draft-07 has included these new keywords if, then and else which allow you to have conditional schemas.



        In this example:




        • Only the foo property is required

        • However if foo is set to "bar" then the bar property also becomes required





        var ajv = new Ajv({
        allErrors: true
        });

        var schema = {
        "properties": {
        "foo": {
        "type": "string"
        },
        "bar": {
        "type": "string"
        },

        },
        "required": ["foo"],
        "if": {
        "properties": {
        "foo": {
        "enum": ["bar"]
        }
        }
        },
        "then": {
        "required": ["bar"]
        }
        }

        var validate = ajv.compile(schema);

        test({
        "foo": "bar",
        "bar": "baz"
        }); // VALID

        test({
        "foo": "xyz"
        }); // VALID

        test({
        "foo": "bar",
        }); // NOT VALID


        function test(data) {
        var valid = validate(data);
        if (valid) console.log('VALID', data);
        else console.log('NOT VALID', data);
        }

        <script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.5.5/ajv.min.js"></script>





        Hopefully this makes sense and you can adapt your code accordingly.



        PS: in your schema you have the require property which I'm not sure is a valid JSON Schema keyword. You probably meant required instead.






        var ajv = new Ajv({
        allErrors: true
        });

        var schema = {
        "properties": {
        "foo": {
        "type": "string"
        },
        "bar": {
        "type": "string"
        },

        },
        "required": ["foo"],
        "if": {
        "properties": {
        "foo": {
        "enum": ["bar"]
        }
        }
        },
        "then": {
        "required": ["bar"]
        }
        }

        var validate = ajv.compile(schema);

        test({
        "foo": "bar",
        "bar": "baz"
        }); // VALID

        test({
        "foo": "xyz"
        }); // VALID

        test({
        "foo": "bar",
        }); // NOT VALID


        function test(data) {
        var valid = validate(data);
        if (valid) console.log('VALID', data);
        else console.log('NOT VALID', data);
        }

        <script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.5.5/ajv.min.js"></script>





        var ajv = new Ajv({
        allErrors: true
        });

        var schema = {
        "properties": {
        "foo": {
        "type": "string"
        },
        "bar": {
        "type": "string"
        },

        },
        "required": ["foo"],
        "if": {
        "properties": {
        "foo": {
        "enum": ["bar"]
        }
        }
        },
        "then": {
        "required": ["bar"]
        }
        }

        var validate = ajv.compile(schema);

        test({
        "foo": "bar",
        "bar": "baz"
        }); // VALID

        test({
        "foo": "xyz"
        }); // VALID

        test({
        "foo": "bar",
        }); // NOT VALID


        function test(data) {
        var valid = validate(data);
        if (valid) console.log('VALID', data);
        else console.log('NOT VALID', data);
        }

        <script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.5.5/ajv.min.js"></script>






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 20 at 21:27









        customcommander

        1,173617




        1,173617






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53398519%2fjson-schema-conditional-require-and-not-require%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Tonle Sap (See)

            I get strange results when I access the Sqlitedatabase with Unity C# via XAMPP

            Guatemaltekische Davis-Cup-Mannschaft