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
Related
I'm not sure there's even a way to do this. But what I want to achieve is the following: I want a JSON schema to enforce that a certain object contains a property that is a reference to an id of another object.
Here's a simplified example:
{
"objectA": {
"#id": "obj-a-001",
"#ref": "obj-b-001"
},
"objectB": {
"#id": "obj-b-001",
"props": "whatever"
}
}
As you can see, objectA has a reference to the #id of objectB.
Now I'd like to be able to enforce this with a json schema: It should be valid if there is an object that has the ID that is used in the reference; but it should give an error if there isn't.
So, basically what XML can do with id and ref.
(I don't mind how exactly this is represented in json: could just as well be id or $id or something like this.)
Is this even possible in json schema? and if so, how? I couldn't find anything in the documentation.
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.
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.
Is there another way to track what is unmarshalled than write own reverter for each field?
I'm updating my local data based on json message and my problem is (simplified):
I'm expecting json like
{ "items": [ { "id":1, "name":"foobar", "price":"12.34" } ] }
which is then unmarshaled to class TItems by
UnMarshaller.TryCreateObject( TItems, TJsonObject( OneJsonElement ), TargetItem )
My problem is that I can't make difference between
{ "items": [ { "id":1, "name":"", "price":"12.34" } ] }
and
{ "items": [ { "id":1, "price":"12.34" } ] }
In both cases name is blank and i'd like to update only those fields that are passed on json message. Of course I could create a reverted for each field, but there are plenty of fields and messages so it's quite huge.
I tried to look REST.Jsonreflect.pas source, but couldn't make sense.
I'm using delphi 10.
In Rest.Json unit there is a TJson class defined that offers several convenience methods like converting objects to JSON and vice versa. Specifically, it has a class function JsonToObject where you can specify options like for example ignore empty strings or ignore empty arrays. I think the TJson class can serve you. For unmarshalling complex business objects you have to write custom converters though.
Actually, my problem was finally simple to solve.
Instead of using TJSONUnMarshal.tryCreateObject I use now TJSONUnMarshal.CreateObject. First one has object parameters declared with out modifier, but CreateObject has Object parameter var modifier, so I was able to
create object, initalize it from database and pass it to CreateObject which only modifies fields in json message.
I am sending messages in JSON format to an ActiveMQ server. I am trying to use JMS Transformation to transform the JSON encoded object into a true Java Object in hopes of being able to use selectors on the data inside.
Here is a link to the documentation on Stomp and Message Transformation.
Here is a link to a discussion on the patch where someone shows an example of a legal JSON object
The format of the JSON objects I am sending (in pretty print) are similar to this:
{
"msg": {
"flag1" : "value1",
"flag2" : "value2"
}
}
The messages arrive in the message queue, but with the transformation-error property set to 'msg : msg'.
The only format accepted by the transformation jms-map-json or jms-object-json is a simple Map format, which in JSON is:
{"map" :
{"entry" :
[
{ "string1": [ "key1", "value1" ] },
{ "string2": [ "key2", "value2" ] }
]
}
}
This is the same format shown in the discussion forum. This format represents a name/value pair map object in java.
Selectors are only usable on Properties and Headers.
you can use any JSON notation for your jms-object-json transformations as long as XStream can handle it. You can take a look at test cases for some examples. There, we use SamplePojo class:
https://svn.apache.org/repos/asf/activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/SamplePojo.java
which is properly annotated so it can be represented with the following JSON
{"pojo":{
"name":"Dejan",
"city":"Belgrade"
}}
You can try using the same approach for your classes.
Hope this helps,
Dejan
It should be mentioned that ActiveMQ version must at least 5.8, because with 5.6 version I had problem when transformation just did not work.