Mr T.
Mr T.

Reputation: 4508

json schema validation of array that can contain either strings or objects

I have a JSON file that contains an array of objects with a single property that is either a string or an array. If it is an array - its items are either a string or an object:
This is my JSON schema:

{
  "$id": "https://mycomp.com/myjson.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "data",
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "data": {
        "anyOf": [
          {
            "$ref": "#/$defs/file"
          },
          {
            "$ref": "#/$defs/inline"
          }
        ]
      }
    }
  },
  "$defs": {
    "file": {
      "type": "string"
    },
    "inline": {
      "type": "array",
      "items": {
        "anyOf": [
          {"type":  "string"},
          {"type":  "object"}
        ]
      }
    }
  }
}

When I validate this JSON - it returns valid and I don't know why.

[
  {
    "data": [
      "This is a string",
      {"prop1": 1, "prop2": "2"}
    ]
  }
]

It will be valid even if I change the "anyOf" to "oneOf". How can I achieve exclusive or on the item type?

Upvotes: 0

Views: 52

Answers (1)

Jeremy Fiel
Jeremy Fiel

Reputation: 3307

I believe this is what you're after. Your instance provided fails this schema.

{
    "$id": "https://mycomp.com/myjson.schema.json",
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "data",
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "data": {
                "anyOf": [
                    {
                        "$ref": "#/$defs/file"
                    },
                    {
                        "$ref": "#/$defs/inline"
                    }
                ]
            }
        }
    },
    "$defs": {
        "file": {
            "type": "string"
        },
        "inline": {
            "type": "array",
            "oneOf": [
                {
                    "items": {
                        "type": "string"
                    }
                },
                {
                    "items": {
                        "type": "object"
                    }
                }
            ]
        }
    }
}

A passing schema would be either of the following:

[
  {
    "data": [
      "This is a string"
    ]
  }
]
[
  {
    "data": [
      {"prop1": 1, "prop2": "2"}
    ]
  }
]

Upvotes: 0

Related Questions