How to use additionalProperties with allOf in JSON schema? - json

Consider this example:
"allOf": [
{"$ref": "test-address-prefix-types-base.json#"},
{
"properties": {}, "additionalProperties" : false
}
]}
When I validate this with Java schema validator, I get error saying:
"keyword":"additionalProperties","message":"object instance has properties which are not allowed by the schema: [\"attributes\",\"type\"]"}]
but the same JSON object validated against the base schema (test-address-prefix-types-base) passes without error.
The referenced schema (base one) doesn't have additionalProperties set.
This is the json message I am using:
String message = "{\"data\":{\"attributes\":{" +
"\"notation\": \"A\"," +
"\"prefixType\": \"A\"}" +
",\"type\":\"test-address-prefix-types\"}}";
Have I missed anything in schema?
Thanks

Your schema could be expanded this way:
allof: It must validate independently against two schemas:
First one with arbitrary properties linked through ref.
The second one which does not allow any property "additionalProperties" : false except those defined in the empty set "properties" : {}. In other words, it can not have any property.
This problem may be solved in draft-5 of the standard. More on this in the following SO question.

Related

How to specify the $schema for a JSON array

I have a json schema for an array. The schema is correct and my array can validate against it. Now I would like to define the schema in the json like i could do with an object like this :
{
"$schema": "pathtomyschema",
"prop1": "value",
...
}
Obvisouly I can't simply set $schema in the array like this :
[
"$schema": "pathtomyschema",
{ "prop1": "value" },
...
]
So, is there any way to do this ?
The goal here is to help people create their json with schema reference.
$schema does not work on JSON instances in general. it is a keyword for schemas to declare what metaschema they use. information on what schema describes an instance is out-of-band to the instance.
if your instance is accessed over http, the recommended method to communicate what schema describes an instance is the 'describedby' link header - see http://json-schema.org/draft/2020-12/json-schema-core.html#rfc.section.9.5.1.1

Deriving property names from values of another enum valued key in jsonschema

Problem:
The requirement to allow only those property Names in an object which are part of an array value of another property in the schema (another property's value dependant property names).
Detailed Explanation:
I have the following JSON:
{
"validResources":["ip","domain","url"],
"resources":
{
"ip" : "192.168.1.1",
"domain" : "www.example.com",
}
}
I would want to write a JSON schema that allows only those keys in "resources" which are part of the array list value of "validResources".
The above JSON is a valid JSON as the "ip" and "domain" keys are actually part of the array items which is a value of the property "validResources".
However, the below JSON should return an error as "file" is not a valid resource as it is not part of the "validResorces" array.
{
"validResources":["ip","domain","url"],
"resources":
{
"ip" : "192.168.1.1",
"file" : "file://etc/passwd" <= No such resource in "validResources"
}
}
What I have tried ?
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type" : "object",
"properties" : {
"validResources" : { "type" : "array",
"minItems" : 1,
"uniqueItems" : true
},
"resources":{
"type":"object",
===Unable to proceed beyond this ===
}
},
}
Other Searches:
I checked propertyNames, however, it can derive only from another schema or have a regex pattern defined as part of its schema. But in this case, the propertyNames / keys within "resources" are dependent on values of the "validResources" property which are not known prior hand and "resources" should allow only those strings/names as its properties which are part of values in array list of "validResources".
There is a pending issue somewhat similar to this question here.
Such a problem cannot be solved as on date with json schema where draft 7 being the latest draft while writing this post.
This question also relates to multiple issues already mentioned in github issues of json-schema spec. Apparently a proposal related to solving such issue is being tracked actively here.
Since this deals with lookup from the value of instance of json schema and not the structural validation alone (which has been the primary motive of existence of json schema standard as on date), this probably has to be dealt differently as of now until next draft comes or the mentioned issue is taken up.

JSON schema conditional check in JSON object within array

Here is the desired schema and json for illustration purpose. Please see the link below.
JSON Schema and JSON
{
"id": "123" ,
"ts": "1234567890",
"complex_rules":
[
{
"type":"admin",
"rule":{
"rights":"all",
"remarks": "some admin remarks"
}
},
{
"type":"guest",
"rights": "limited"
},
{
"type":"anonymous",
"rights": "blocked"
}
]
}
The 'complex_rules' is an array of json object:
With type either be a : "admin", "guest", "anonymous" and the 'type' attribute is MANDATORY.
Each object in array can have its own structure, but the type can be either of: "admin", "guest", "anonymous" only. No other type attribute is acceptable.
The conditions to evaluate:
The type of object in the array cannot re-occur in the array. (I know this seems to be not possible, so we can ignore this)
If attribute "rights" in the {type=admin object} with any value, then we cannot have "rights": "limited" or any value in {type=guest object}. The JSON Schema validation must complain about this.
Another twist, either object {type":"guest"}or {type":"anonymous"} can exist. Both types cannot coexist along with other types.
----Update
The above link is the solution this question.
In regards to 1 and 2:
You need to use a combination of if, then, and not keywords to construct the logic you require with the correct level of applicability.
In regards to 3:
The type of object in the array cannot re-occur in the array. (I know
this seems to be not possible, so we can ignore this)
Right, that's correct, it's not possible as of draft-7 JSON Schema.

What is the logical relationship between keyword in a json schema?

According to the specification (http://json-schema.org/schema) there is no mutual exclusion among schema keywords.
For example I could create the following schema:
{
"properties" : {
"foo" : {"type" : "string"}
}
"items" : [
{"type" : "integer" },
{"type" : "number" }
]
}
Would this schema validate against both objects and arrays?
If so it would imply an "OR" relationship between keyword.
But if we consider the following schema:
{
"anyOf" : [
{ "type" : "string",},
{ "type" : "integer"}
]
"not" : {
{ "type" : "string",
"maxLength" : 5
}
}
}
The most practical way to interpret it would be an "AND" relationship between anyOf and not keywords.
I could not find any indication in the draft v4 on how keywords logically interact. Can anyone point me to a documentation/standard that would answer this question?
Keywords are always an "AND" relationship. Data must satisfy all keywords from a schema.
The properties and items keywords don't specify the type of the object (you have to use type for that). Instead, they only have meaning for particular types, and are ignored otherwise. So properties actually means:
If the data is an object, then the following property definitions apply...
This means that {"properties":{...}} will match any string, because properties is ignored for values that aren't objects. And items actually means:
If the data is an array, then the following item definitions apply...
So the AND combination looks like:
(If the data is an object, then properties applies) AND (if the data is an array, then items applies)
As the spec clearly dictates, some keywords are only relevant for one particular type of JSON value, or all of them.
So, for instance, properties only applies if the JSON value you validate is a JSON Object. On any JSON value which is NOT an object, it will not apply (another way to understand it is that if the JSON value to validate is not a JSON Object, validation against this keyword will always succeed).
Similarly, items will only apply if the JSON value is a JSON Array.
Now, some other keywords apply for all types; among these are enum, allOf, anyOf, oneOf, type. In each case, the validation rules are clearly defined in the specification.
In short: you should consider what type of value is expected. The easiest way to force a value to be of a given type in a schema is to use type, as in:
"type": "integer"
BUT this keyword will nevertheless be applied INDEPENDENTLY of all others in the validation process. So, this is a legal schema:
{
"type": "integer",
"minItems": 1
}
If an empty JSON Array is passed for validation, it will fail for both keywords:
type because the value is not an array;
minItems because the value is an array but it has zero elements, which is illegal for this particular keyword since it expects one element in the array at least.
Note that the result of validation is totally independent of the order in which you evaluate keywords. That is a fundamental property of JSON Schema. And it is pretty much a requirement that it be so, since the order of members in a JSON Object is irrelevant ({ "a": 1, "b": 2 } is the same JSON Object as { "b": 2, "a": 1 }).
And of course, if only ONE keyword causes validation to fail, the whole JSON value is invalid against the schema.

Can I get MOXy to not output an element when generating json?

An instance of my JAXB Object model contains an element that I want output when I generate Xml for the instance but not when I generate json
i.e I want
<release-group>
<type>Album</type>
<title>Fred</title>
</release-group>
and
"release-group" : {
"title" : "fred",
},
but have
"release-group" : {
"type" : "Album",
"title" : "fred"
},
Can I do this using the oxml.xml mapping file
This answer shows how I can do it for attributes using the transient keyword, Can I get MOXy to not output an attribute when generating json? but I cannot get that to work for an element.
Sorry problem solved, a bit of confusion on my part.
The example I gave above didn't actually match the true situation accurately, type was actually output as an attribute for Xml, but use of transient didnt work because it had been renamed in the JAXB
#XmlAttribute(name = "target-type", required = true)
#XmlSchemaType(name = "anyURI")
protected String targetType;
So adding
<java-type name="ReleaseGroup">
<java-attributes>
<xml-transient java-attribute="targetType"/>
</java-attributes>
</java-type>
worked, previously I was incorrectly doing
<java-type name="ReleaseGroup">
<java-attributes>
<xml-transient java-attribute="target-type"/>
</java-attributes>
</java-type>