JSON Schema definition for array of objects
You have defined your schema correctly, except that it doesn't match the data you say you are validating. If you change the property names to match the schema, you still have one issue. If you want to allow "toll" and "message" to be null, you can do the following.
{
"type": "array",
"items": {
"type": "object",
"properties": {
"loc": {
"type": "string"
},
"toll": {
"type": ["string", "null"]
},
"message": {
"type": ["string", "null"]
}
},
"required": [
"loc"
]
}
}
However, that isn't related to the error message you are getting. That message means that data you are validating is not an array. The example data you posted should not result in this error. Are you running the validator on some data other than what is posted in the question?
How to write a JSON schema for array of objects?
From the JSON schema spec, section 5.5. items:
When this attribute value is an array of schemas and the instance
value is an array, each position in the instance array MUST conform
to the schema in the corresponding position for this array. This
called tuple typing.
Your schema definition requires the first three elements of the array to be exactly those 'a', 'b' and 'c' elements. If items
is left empty, any array element is allowed. Similarly, if additionalItems
is left empty, any additional array element is allowed.
To get what you want, you need to specify "additionalItems": false
and for the items
, I think the following (somewhat shortened from your definitions) should work:
"items": {
"type": [
{"type":"object", "properties": {"a": {"type": "object", "properties": {"ax": { "type":"number"}}}}},
{"type":"object", "properties": {"b": {"type": "object", "properties": {"bx": { "type":"number"}}}}},
{"type":"object", "properties": {"c": {"type": "object", "properties": {"cx": { "type":"number"}}}}}
]
}
Json schema array of objects (where objects must be the same)
Your issue is that your schema describe an array of exactly one element.
For example this:
{
"type": "array",
"items": [
{ "const": 42 }
]
}
Is the same as this:
{
"type": "array",
"minItems": 1,
"maxItems": 1,
"items": [
{ "const": 42 }
]
}
Which will validate this and only this array: [42]
If your array can contain zero or more elements of the same shape this is how I would do it:
{
"type": "array",
"items": {
"const": 42
}
}
Which would validate []
, [42]
, [42, 42]
, [42, 42, 42]
, ... but not [42, 43]
for example.
So to answer your question your schema should be:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"Fuses": {
"type": "array",
"items": {
"type": "object",
"properties": {
"Foo": {
"type": "integer"
}
},
"required": [
"Foo"
]
}
}
},
"required": [
"Fuses"
]
}
JSON schema for an object whose value is an array of objects
You actually only have one line in the wrong place, but that one line breaks the whole schema. "person" is a property of the object and thus must be under the properties
keyword. By putting "person" at the top, JSON Schema interprets it as a keyword instead of a property name. Since there is no person
keyword, JSON Schema ignores it and everything below it. Therefore, it is the same as validating against the empty schema {}
which places no restrictions on what a JSON document can contain. Any valid JSON is valid against the empty schema.
{
"type" : "object",
"properties" : {
"person" : {
"type" : "array",
"items" {
"type" : "object",
"properties" : {
"name" : {"type" : "string"}
"age" : {"type" : "integer"}
}
}
}
}
}
By the way, there are several online JSON Schema testing tools out there that can help you out when crafting your schemas. This one is my goto http://jsonschemalint.com/draft4/#
Also, here is a great JSON Schema reference that might help you out as well: https://spacetelescope.github.io/understanding-json-schema/
How can a json schema represent an array with different objects?
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.
let 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.
How to define a JSON schema where an array of objects contains at least the elements with the expected names
Let's first look at it using some draft-06 or higher keywords because it's easier to understand. Then we'll translate it to draft-04.
We can use the contains
keyword to assert that an array contains at least one item that matches a schema. This example shows asserting that an array must contain an object with a property "name" whose value is "a"
.
{
"contains": {
"type": "object",
"properties": {
"name": { "const": "a" }
},
"required": ["name"]
}
}
You can combine multiple assertions like this these using allOf
to assert for "b" and "c" as well.
{
"allOf": [
{ "$ref": "#/definitions/contains-a" },
{ "$ref": "#/definitions/contains-b" },
{ "$ref": "#/definitions/contains-c" }
]
}
Now we need to translate to draft-04. const
is easy.
{ "const": "a" }
becomes
{ "enum": ["a"] }
The transformation for contains
is far less intuitive, but it works. I suggest putting them in definitions
(like shown in the allOf
example) to make your schema more readable.
{ "contains": { "$ref": "#/definitions/name-a" } }
becomes
{
"not": {
"items": {
"not": { "$ref": "#/definitions/name-a" }
}
}
}
JSON Schema - array with multiple different object types
You have it slightly wrong. Currently your schema says... for the pipeline array, either, all of the items must be foo
or all of the items must be baz
.
You need to change your location of anyOf
and items
...
items
applies to every item in the array.anyOf
checks that any of the subschema values are valid against the instance location (in this case, each item in the array).
{
"$id": "https://example.com/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"pipeline": {
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"additionalProperties": false,
"properties": {
"foo": {
"type": "string"
},
"someOption": {
"type": "integer"
}
},
"required": [
"foo"
]
}, {
"type": "object",
"additionalProperties": false,
"properties": {
"baz": {
"type": "string"
},
"anotherOption": {
"type": "integer"
}
},
"required": [
"baz"
]
}
]
}
}
}
}
JSON-schema object array validation
Two things. You have a typo in your items
schema where you actually want to have type
and not conditionsType
. Secondly, if the items keyword is an array, the items of the array are validated against the schemas in this order. You want to have the items
keyword as a single schema which is then applied to all items. Your corrected schema for copy-paste:
{"$schema":"http://json-schema.org/draft-07/schema","title":"Some schema","description":"Some schema","type":"object","required":["header","data"],"properties":{"header":{"type":"object","required":["action","taskGuid","publishDate"],"properties":{"action":{"enum":["create_work_order","change_time","cancel_work"]},"taskGuid":{"type":"string"},"publishDate":{"type":"string","format":"date-time"}}},"data":{"type":"object","required":["code","conditions"],"properties":{"code":{"type":"string"},"conditions":{"type":"array","items":{"type":"object","properties":{"conditionsType":{"enum":["A","B","C"]},"dateBegin":{"type":"string","format":"date-time"},"dateEnd":{"type":"string","format":"date-time"}},"required":["conditionsType","dateBegin","dateEnd"]}}}}}}
json schema for an array of items (referenced earlier in the schema)
The $ref
should be contained directly in the items
keyword and not under items.type
.type
is a reserved keyword that can only be a string or an array but not an object. That makes your schema invalid.
This would be a valid schema (omitting some details for readability):
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"proj": {
"type": "object"
}
},
"type": "array",
"items": {
"$ref": "#/definitions/proj"
}
}
Related Topics
Cheat Sheet for All Design Patterns Implemented in Ruby
How to Make a Ruby Script Run Once a Second
Add a Callback Function to a Ruby Array to Do Something When an Element Is Added
Read Contents of a Local File into a Variable in Rails
Parsing JSON Without Quoted Keys
How to Do Named Capture in Ruby
Is Assignment in a Conditional Clause Good Ruby Style
Iterate an Array, N Items at a Time
Is It a Bad Idea to Reload Routes Dynamically in Rails
Ruby Escape Argv Argument or String as Argument to Shell Command
Initializing Instance Variables in Mixins
How to Print Information About a Net:Httprequest for Debug Purposes
Where to Insert Rack::Deflater in the Rack
Are There Any Good Mutation Testing Tools for Ruby 1.9 and Rspec2
Where Does Ruby Keep Track of Its Open File Descriptors
Machinist VS Factorygirl - Pros and Cons