Dynamic list of valid values in JSON Schema - json

Given the following JSON, how can I use JSON Schema to validate that each string in nodes[].targets matches the name of a listed node?
{
"nodes": [
{"name": "app_server"},
{"name": "web_server1"}
{"name": "web_server2"}
{
"name": "load_balancer",
"targets": ["web_server1", "web_server2"]
}
]
}

JSON schema does not support such validation criteria.
You either need to define custom keywords if the validator supports them (e.g. in Ajv) or validate outside of schema.
Disclaimer: I have created Ajv.

Related

JSON Schema object properties defined by enum

I'm attempting to reuse an enum in my JSON Schema to define the properties for an object.
I was wondering if the following is correct.
JSON Schema
{
"type": "object",
"propertyNames": {
"enum": ["Foo","Bar"]
},
"patternProperties": {
".*": {
"type": "number"
}
}
}
JSON Data
{
"Foo": 123,
"Bar": 456
}
The reason I ask is that I get inconsistent results from JSON Schema validation libraries. Some indicate the JSON validates, while others indicate the JSON is invalid.
p.s. if anyone is wondering "why" I'm trying to define the properties with an enum, it is because the enum is shared in various parts of my json schema. In some cases it is a constraint on a string, but I need the identical set of possible values both on those string properties and also on the object properties. As an enum I can maintain the set of possible values in one place.
Yes, that's a valid JSON Schema. You could also express it like this:
{
"type": "object",
"propertyNames": {
"enum": ["Foo","Bar"]
},
"additionalProperties": {
"type": "number"
}
}
It says "all property names must conform to this schema: (one of these values listed in the enum); also, all property values must conform to this schema: (must be numeric type)."
What errors do you get from the implementations that report this as invalid? Those implementations have a bug; would you consider reporting it to them?

Including the namespace property when Serializing using Microsoft-Avro-Core

I am serializing C# objects to an avro file format using the Microsoft-Avro-Core nuget package. The issue I am having is that the avro schema contains a namespace property in the json schema definition, which is not included in the schema of the serialized avro file.
ex.
{
"name": "typeName",
"type": [
{
"type": "record",
"name": "recordName",
"namespace": "topLevelRecord.record_data",
"fields": [
]
},
"null"
]
}
after serializeing, to avro, the containing schema definition is written without the namespace like so:
{
"name": "typeName",
"type": [
{
"type": "record",
"name": "recordName",
"fields": [
]
},
"null"
]
}
This is creating an issue for us since the consuming code no longer contains the namespace. How can I tell the serializer to include the namespace property in the serialized avro file.
Setting the Name and Namespace properties of the DataContract attribute does not work. It simply prefixes the serialized name property with the namespace. Which is not what we need.
We are using the SequentialWriter to serialize a collection of records. The AvroSerializationSettings object does not contain a property to enforce the serialization of the namespace.
Any help would be much appreciated.
Thanks
So after some research, it turns out the RecordSchema serializer doesn't include the namespace. After reviewing the code on github, it uses the FullName property as the name and leaves out the namespace.
Microsoft.Avro-Core
We did not define the schema. But we have to use it. In order to be compliant the serialized schema must include the namespace.

How to validate number of properties in JSON schema

I am trying to create a schema for a piece of JSON and have slimmed down an example of what I am trying to achieve.
I have the following JSON schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Set name",
"description": "The exmaple schema",
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"additionalProperties": false
}
The following JSON is classed as valid when compared to the schema:
{
"name": "W",
"name": "W"
}
I know that there should be a warning about the two fields having the same name, but is there a way to force the validation to fail if the above is submitted? I want it to only validate when there is only one occurrence of the field 'name'
This is outside of the responsibility of JSON Schema. JSON Schema is built on top of JSON. In JSON, the behavior of duplicate properties in an object is undefined. If you want to get warning about this you should run it through a separate validation step to ensure valid JSON before passing it to a JSON Schema validator.
There is a maxProperties constraint that can limit total number of properties in an object.
Though having data with duplicated properties is a tricky case as many json decoding implementions would ignore duplicate.
So your JSON schema validation lib would not even know duplicate existed.

Use custom type in JSON Schema

One have the following JSON object:
{
"index": 10,
"data": "<?xml version=\"1.0\"?>..."
}
the corresponding schema:
{
"title": "Example",
"type": "object",
"properties": {
"index": {
"type": "integer"
},
"data": {
"type": "string"
}
}
}
What I'm trying to achieve is to validate XML inside data property with XSD schema.
How to represent XML data type with xsd schema attribute correctly from the point of JSON Schema specs?
Short answer
You can't
Long answer
You really can't. No JSON processor in the history of mankind will be able to validate inline XML against an XSD.
The only thing you can do is include the XSD file as text and then the consumer of the JSON can then do the validation on their side. Or, even better, validate the XML before you place it in the JSON doc.

JSON schema reference another element in the document

Is there a way to express reference to another element in the same JSON document using JSON schema? The title might be a bit confusing, but i'm not looking for the "$ref" attribute, which references another type, but I'm curious, if there is a way, to reference another element in the document using a specified field. I know this is possible to enforce using xsd for xml documents, not sure about JSON.
I want to do something like this:
{
"people": [
{ "id": "1", "name": "A" },
{ "id": "2", "name": "B" },
{ "id": "3", "name": "C" }
],
"chosenOne": "1" // I want the schema to enforce a person ID here
}
I have been looking at the schema definition of v4: http://json-schema.org/draft-04/schema but didn't find anything, that looks like what I'm trying to do. Did I just miss it?
What you want is that you describe a reference ($ref) in the object your schema is describing.
kind of like this
{
"people": []
"chosenOne": { $ref: "#1"}
}
(or maybe a pointer if you want the value of the Id (https://json-spec.readthedocs.io/pointer.html)
I know of no direct way to do this but you might be able to use the pattern or oneof properties to force it being the right value. Kind of like this
"properties": {
"chosenOne"
"type": "string",
"oneOf": ["1","2","3"]
]
},
}
Similarly you could force the value of the property to be a reference pattern. That said since there is no reference value type (http://www.tutorialspoint.com/json/json_data_types.htm) only number or string you can't guarantee the meaning of the value. You can just guarantee that if follows some kind of reference pattern.
If you need more than what json schema's can give you you might want to look in odata for example. OData has some extra things so you can describe an entitySet and then define a navigation property to that set.
It does however force you to follow the odata structure so you aren't as free as you would be with a regular json schema.