I asked this same question on the JSON schema google group, and it was answered quickly. User fge asked that I post his response here:

Hello,

The current specification is draft v4, not draft v3. More specifically, the validation specification is here:

https://datatracker.ietf.org/doc/html/draft-fge-json-schema-validation-00

The web site is not up to date, I don't know why... I'll submit a pull request.

With draft v4 you can use this:

{
    "type": "array",
    "items": {
        "oneOf": [
            {"first": [ "schema", "here" ] }, 
            {"other": [ "schema": "here" ] }
        ]
    }  
}

For instance, this is a schema for an array where items can be either strings or integers (it can be written in a more simple way though):

{
    "type": "array",
    "items": {
        "oneOf": [
            {"type": "string"},
            {"type": "integer"}
        ]
    }
}

This is the correct answer. My corrected schema now includes:

"transactions" : {
    "type" : "array",
    "items" : {
        "oneOf" : [
            {
                "type" : "object",
                "properties" : {
                    "type" : {
                        "type" : "string",
                        "enum" : ["BUILD", "REASSIGN"]
                    }
                }
            },
            {
               "type" : "object",
               "properties" : {
                 "type" : {
                   "type" : "string",
                   "enum" : ["BREAK"]
                  }
               }
            }
        ]
    }
}
Answer from deepwinter on Stack Overflow
🌐
JSON Schema
json-schema.org › understanding-json-schema › reference › array
JSON Schema - array
However, the json module in the Python standard library will always use Python lists to represent JSON arrays. ... List validation: a sequence of arbitrary length where each item matches the same schema. Tuple validation: a sequence of fixed length where each item may have a different schema.
Top answer
1 of 5
73

I asked this same question on the JSON schema google group, and it was answered quickly. User fge asked that I post his response here:

Hello,

The current specification is draft v4, not draft v3. More specifically, the validation specification is here:

https://datatracker.ietf.org/doc/html/draft-fge-json-schema-validation-00

The web site is not up to date, I don't know why... I'll submit a pull request.

With draft v4 you can use this:

{
    "type": "array",
    "items": {
        "oneOf": [
            {"first": [ "schema", "here" ] }, 
            {"other": [ "schema": "here" ] }
        ]
    }  
}

For instance, this is a schema for an array where items can be either strings or integers (it can be written in a more simple way though):

{
    "type": "array",
    "items": {
        "oneOf": [
            {"type": "string"},
            {"type": "integer"}
        ]
    }
}

This is the correct answer. My corrected schema now includes:

"transactions" : {
    "type" : "array",
    "items" : {
        "oneOf" : [
            {
                "type" : "object",
                "properties" : {
                    "type" : {
                        "type" : "string",
                        "enum" : ["BUILD", "REASSIGN"]
                    }
                }
            },
            {
               "type" : "object",
               "properties" : {
                 "type" : {
                   "type" : "string",
                   "enum" : ["BREAK"]
                  }
               }
            }
        ]
    }
}
2 of 5
7

I've been looking into this for quite a while too. But haven't been able to find a working solution. It works fine if you have only one schema eg.

"transactions" : {
          "type" : "array",
          "items" : 
          {
            "type" : "object",
            "properties" : {
              "type" : {
                "type" : "string",
                "enum" : ["BREAK"]
              },
          }
}

Then you just skip the array brackets, and use an object. However if you want to do what you are doing, there seems to be no solid answer. This is the only thing that I've found so far: http://the-long-dark-tech-time.blogspot.se/2012/12/using-json-schema-with-array-of-mixed.html

🌐
JSON Schema
json-schema.org › learn › miscellaneous-examples
JSON Schema - Miscellaneous Examples
The fruits property contains an array of strings, while the vegetables property contains an array of objects, each adhering to the "veggie" schema definition. This example introduces the enum validation keyword which is used with an array of values that includes an integer (42), a boolean (true), a string ("hello"), null, and an array ([1, 2, 3]). This demonstrates how enum can be used to specify a set of allowed values of different types.
🌐
Json-schema
tour.json-schema.org › content › 01-Getting-Started › 06-Array-of-Objects
Array of Objects: Getting Started | A Tour of JSON Schema
1{ 2 "skills": { 3 "type": "array", 4 "items": { 5 "type": "object", 6 "properties": {...} 7 } 8 } 9} Now, try to modify the skills property in the schema given to you in the side editor, and make it an array of objects with name and level properties.
🌐
Cswr
cswr.github.io › JsonSchema › spec › arrays
Arrays - JSON Schema
Here we show how to specify collections of JSON types using possibly nested JSON Schemas. Arrays are used to represent ordered sets of values, such as the following sequence of strings:
🌐
JSON Schema
json-schema.org › understanding-json-schema › reference › object
JSON Schema - object
The required keyword takes an array of zero or more strings. Each of these strings must be unique. ... In Draft 4, required must contain at least one string. In the following example schema defining a user record, we require that each user has a name and e-mail address, but we don't mind if they don't provide their address or telephone number: ... { "type": "object", "properties": { "name": { "type": "string" }, "email": { "type": "string" }, "address": { "type": "string" }, "telephone": { "type": "string" } }, "required": ["name", "email"]}
🌐
Cswr
cswr.github.io › JsonSchema › spec › multiple_types
Multiple Types - JSON Schema
In general, when multiple (or no) ... that are of the type that is compatible with the keyword. As another example, the following schema specifies JSON documents that are either arrays, strings, integers, numbers, boolean or nulls, and also objects that have the property ...
Find elsewhere
Top answer
1 of 2
2

Does the second schema correctly identify that "arr is an array of objects that have an integer named type an integer, and either an object named Steps or an object named Heartrate"?

Yes, somewhat. You do not state which properties must exist, and which properties cannot exist together at the same time, which we can do with the "required" and "oneOf" keywords.

Here's an updated schema, and also fixing an error you made in the "Heartrate" section (you said "steps" instead of "heartrates"):

Copy{
  "$schema": "https://json-schema.org/draft/2019-09/schema",
  "type": "object",
  "properties": {
    "arr": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [ "type" ],
        "oneOf": [
           { "required": ["Steps"] },
           { "required": ["HeartRate"] }
        },
        "properties": {
          "type": {
            "type": "integer"
          },
          "Steps": {
            "type": "object",
            "required": ["steps"],
            "properties": {
              "steps": {
                "type": "integer"
              }
            }
          },
          "HeartRate": {
            "type": "object",
            "required": ["heartrates"],
            "properties": {
              "heartrates": {
                "type": "integer"
              }
            }
          }
        }
      }
    }
  }
}

2 of 2
1

Well, it passes because technically it is valid, you can have any combination of objects in an array. This schema explicitly states that there can be a heartrate object. You say you're familiar with arrays of a single object type, but what you should know is an array doesn't care what types of objects are in it, which is why your introduced schema is in fact valid. Whether or not it fits the function you're trying to achieve is another question all together.

It would imply that you would need either one very complex loop to traverse the array when you need to pull an object, assuming there will be so many that you can't adequately index them, or you would need some sort of index with address to the objects in the array, which might be cumbersome to write but possible. So the question is, what are you intending to do with these objects? Seems obvious from the properties you're using, seems like a fitness monitor of some sort, but then what your intention to do with the data isn't apparent so it's difficult to say what you could do even if this schema is valid, which keep in mind that it is indeed a valid structure for an array.

Although if you do have two types of objects, one could ask why not simply have an array for each type which will have supporting data pulling functions specific to their contents. But again it asks what you're intending to do.

Hope this helps your thought process.

UPDATE...

Not knowing exactly what you are intending to do, here is what I suggest you use as your data-structure format.

Copylet someArray = [
  {
    Steps: {
      steps: 3500
    },
    HeartRate: {
      heartrates: 4000
    }
  },
  {
    Steps: {
      steps: 3500
    },
    HeartRate: {
      heartrates: 4000
    }
  }
]

You examples have some redundancy in them it seems, where they are explicitly stating that something is an object and something is a property of that object. JavaScript already knows all that so no need to add more complexity to the functions you create to work with these that will then have to dig through all those layers. I suggest that you create one object and each has a property of the type you've declared that is an object and that object can if you want be expanded or condensed as you desire. This will mitigate a lot of complexity to your structure. And so you'll see that you have an Array of Objects and those objects contain properties representing the data you're intending to gather.

But this assumes that the data you're gathering is from multiple sources. Again would need to know a bit more about what you're trying to accomplish.

🌐
Opis
opis.io › json-schema › 2.x › array.html
Array type | Opis JSON Schema
An array is valid against this keyword if all unchecked items are valid against the schema defined by the keyword value. An item is considered unchecked if items keyword or prefixItems keyword (starting with draft 2020-12) contains an array of schemas and doesn’t have a corresponding position (index). The value of the keyword must be a valid json schema (object, boolean).
🌐
IBM
ibm.com › docs › en › cics-ts › 6.x
Variable arrays of elements in DFHJS2LS
JSON can contain arrays of varying numbers of elements. In general JSON Schemas that contain varying numbers of elements do not map efficiently into a single high-level language data structure. CICS uses container-based mappings or inline mappings to handle varying numbers of elements in JSON data.
🌐
GitHub
github.com › java-json-tools › json-schema-validator › issues › 46
Using JSON schema with an array of mixed object types · Issue #46 · java-json-tools/json-schema-validator
December 9, 2012 - as far as I understand - this should be a valid schema: { "type" : "array", "items" : { "type" : [ { "type" : "object", "properties" : { "name" : { "type" : "string" }}}, { "type" : "object", "properties" : { "price" : { "type" : "number...
Author   ettig
🌐
GitHub
github.com › orgs › json-schema-org › discussions › 145
Contains not working as expected with array of objects · json-schema-org · Discussion #145
{ "$schema": "http://json-schema.org/draft-07/schema", "properties": { "elements": { "type": "array", "items": { "type": "object" }, "contains": { "properties": { "somePropertyA": { "type": "string", "enum": [ "true" ] } } } } }, "required":["elements"], }
🌐
Liquid Technologies
liquid-technologies.com › Reference › XmlStudio › JsonSchemaEditor_Property_AdditionalItems.html
Additional Items
The first 3 objects in the instance array must validate against the corresponding schema, but any additional items must validate against the [3-n] schema. In this version of the standard we see 'items' renamed to 'prefixItems' and 'additionalItems' renamed 'items'.
🌐
Gsu
tinman.cs.gsu.edu › ~raj › 8711 › sp21 › json › JSONSchema.html
JSON and JSON Schema
Here is a JSON schema that describes the second representation of a person: e1.schema · { "$schema": "http://json-schema.org/schema#", "$id": "http://yourdomain.com/schemas/myschema.json", "type": "object", "properties": { "first_name": { "type": "string" }, "last_name": { "type": "string" }, "birthday": { "type": "string", "format": "date-time" }, "address": { "type": "object", "properties": { "street_address": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" }, "country": { "type" : "string" } } } } }
🌐
Google Groups
groups.google.com › g › json-schema › c › z34YqedG-1s
Array uniqueItems not able to describe object items with specific keys.
The way I split the schemas up ensures that the value equality constraint only applies to the combination of the name and surname fields, and not the entire object. In other words, the lastCheck field does not affect uniqueness, which is what we want. Otherwise, we could have the same person in the list twice simply because lastCheck is set to something different each time.
🌐
Json-schema
tour.json-schema.org › content › 01-Getting-Started › 05-Arrays
Arrays: Getting Started | A Tour of JSON Schema
Learn how to define arrays in JSON Schema using the type and items keywords, and convert properties to arrays of strings.