7

I am trying to define a json schema to limit the properties of objects conatined in an array.

What I have so far is:

{
    "title":"myCollection",
    "properties":{
        "things":{
            "type":"array",
            "items":[{
                "title":"thingObj",
                "type":"object",
                "properties":{
                    "name":{
                        "type":"string"
                    },
                    "code":{
                        "type":"string"
                    },
                    "type":{
                         "type":"string",
                         "enum":["dog","cat"]
                    },
                    "rate":{
                        "type":"number"
                    },
                    "value":{
                        "type":"number"
                    }
                },
                "anyOf":[{
                    "properties":{
                        "name":{
                            "type":"string"
                        }
                    },"required":["name"]
                },{
                    "properties":{
                        "code":{
                            "type":"string"
                        }
                    },"required":["code"]
                },{
                    "properties":{
                        "type":{
                            "type":"string",
                            "enum":["new","existing"]
                        }
                    },"required":["type"]
                }],
                "oneOf":[{
                    "properties":{
                        "rate":{
                            "type":"number"
                        }
                    },
                    "required":["rate"]
                },{
                   "properties":{
                       "value":{
                            "type":"number"
                       }
                   },
                   "required":["value"]
                }],
                "additionalProperties":false
            }]
        }
    }
}

Now given the following jsonobj:

{
    "things": [
        {
            "name": "tabby", 
            "code": "meeow", 
            "type": "cat", 
            "value": 20
        }, 
        {
            "name": "k9", 
            "code": "woofer", 
            "type": "dog",
            "rate": 15
        }
    ]
}

This json schema validator delivers a valid response but this validation only seems to apply to the first element in the array. If you remove all the fields included in the anyOf clause or the oneOf clause on the first element then validation fails. The same on the second array element does not raise the desired failure. How can I ensure the validation is run against each array member?

2 Answers 2

13

This is because you have (accidentally) used "tuple typing". This is enabled when the value of "items" is an array, and it matches schemas to specific positions in the array.

If you change "items" (in your schema) to be simply a schema (not an array of schemas), then it will validate all items the same way.

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

1 Comment

granted you answered this seven(!) years ago, but can you give more detail what you meant by "If you change "items" (in your schema) to be simply a schema (not an array of schemas), then it will validate all items the same way.". I'm stuck trying to define an array where there can be differing number of items which follow the same selection of schemas.
0

Kudos to @cloudfeet 's answer, I was struggling with this issue until I saw his answer. To be more clear, the [] around items should be removed.

{
    "title":"myCollection",
    "properties":{
        "things":{
            "type":"array",
            "items":**[**{
                "title":"thingObj",
                "type":"object",
                .
                .
                .
                   "required":["value"]
                }**]**,
                "additionalProperties":false
            }]
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.