In the spec http://json-schema.org/latest/json-schema-core.html, it only list below types:
null,
boolean,
string,
number,
object,
array.
I know number includes integer, but can I define a "type":"integer" explicitly. I mean will this violate the spec?
Yes, you can use {"type": "integer"} in the schema.
See:
https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-04#section-3.5
https://datatracker.ietf.org/doc/html/draft-fge-json-schema-validation-00#section-5.5.2
Related
Maybe superfluous, but some intro...
I am rewriting an add-in for my CAD-application (using VB.NET).
This add-in reads, via an API, a bunch of metadata from a file, presents it in a Form. This data can then be (partially) changed and written back to the file.
This metadata is accessible in a consistent way, however the data type is not the same everywhere (String, Currency, Date, Boolean, Long and IPictureDisp).
Currently I have a much too complex class with several arrays. I thought it might be smarter to create a structure. The problem is the varying data type.
Is it possible to define a structure with a member with varying datat type, or am I forced to define a different structure for each data type?
You have a few options...
1: Use Object
Nice and simple, every data type inherits from Object - so if your struct contains a property of type Object, you can put pretty much any data type in there
From the docs:
The Object data type can point to data of any data type, including any object instance your application recognizes. Use Object when you do not know at compile time what data type the variable might point to.
However, this does mean that you will get next to no help from the compiler when you are trying to write code using this property. You will also probably have to cast any time you need to do anything type-specific
2: Generic Types
This will not fit situations where you are not sure of the type. You can create a generic struct using the Of syntax.
You'd create it as so:
Structure MyStructure(Of T)
'our changing type
Dim MyCustomData As T
'...alongside regular types
Dim Name As String
Dim OtherThing As Integer
End Structure
and then when you need to create the structure, you'd simply pass the type in and assign the value
Dim struct As New MyStructure(Of Integer)
struct.MyCustomData = 123
Dim struct2 As New MyStructure(Of String)
struct2.MyCustomData = "a"
Out of curiosity, I tried to create an ABAP interface with name object. The compiler gives the error message "OBJECT" is a protected type name and therefore cannot be used for a user's own type definitions.
While this check is certainly a good idea, I could not find a reference to protected type name in the ABAP Keyword documentation. Are there others?
The naming conventions indicate the possible names additionally to the mandatory naming "convention":
The names of predefined ABAP types or predefined data objects must not be used for data types or data objects.
NB: I tried names of predefined data objects, they are allowed for data types, so I guess "respectively" is to be understood implicitly.
Self-defined data types must not have the name of a built-in ABAP type. This applies to type definitions in the ABAP language and in the ABAP Dictionary.
Concerning the generic types, only those made of one word are forbidden, i.e. HASHED, INDEX, SORTED, and STANDARD are allowed (and also REF):
ANY, C, CLIKE, CSEQUENCE, DATA, DECFLOAT, N, NUMERIC, OBJECT, P, SIMPLE, TABLE, X, XSEQUENCE
Other types are protected like the built-in concrete (i.e. not generic) types (error <XXXX> is a protected type name and therefore cannot be used for a user's own type definitions):
D, DECFLOAT16, DECFLOAT34, F, I, STRING, T, XSTRING
CURSOR
Obsolete types 1 and 2 (their names are also forbidden inside classes and interfaces because the name must start with A-Z, underscore).
Other types may be forbidden (error Type <XXXX> is reserved for future further developments of the ABAP language. Choose another name.) like:
INT, INT1, INT2, INT4, INT8
The list is not exhaustive. I didn't find an official list in the ABAP documentation nor in the SAP support Web site.
NB: tests done in a 7.52 system
The generic data types, which cannot be used for naming:
https://help.sap.com/doc/abapdocu_750_index_htm/7.50/en-US/abenbuilt_in_types_generic.htm
The best way to create all of your object or program or table ect.. is to put the Z or the Y before the name you want to give:
Object have to been Zobject or Yobject or ZY-YZobject
Often, we use the Z and then the module wich it refers: ZSD_OBJECT
For the following json string :
{
"abc" : 123,
"def" : 345
}
The following schema considers it valid :
{
"$schema": "http://json-schema.org/draft-03/schema#",
"title": "My Schema",
"description": "Blah",
"type": "object",
"patternProperties": {
".+": {
"type": "number"
}
}
}
However, changing the the patternProperties to properties still considers it valid. What then, is the difference between these 2 tags?
For the schema above all properties should be number. This data is invalid:
{ a: 'a' }
If you replace patternProperties with properties only property '.+' should be number. All other properties can be anything. This would be invalid:
{ '.+': 'a' }
This would be valid:
{ a: 'a' }
The properties (key-value pairs) on an object are defined using the properties keyword. The value of properties is an object, where each key is the name of a property and each value is a JSON schema used to validate that property.
additionalProperties can restrict the object so that it either has no additional properties that weren’t explicitly listed, or it can specify a schema for any additional properties on the object. Sometimes that isn’t enough, and you may want to restrict the names of the extra properties, or you may want to say that, given a particular kind of name, the value should match a particular schema. That’s where patternProperties comes in: it is a new keyword that maps from regular expressions to schemas. If an additional property matches a given regular expression, it must also validate against the corresponding schema.
Note: When defining the regular expressions, it’s important to note that the expression may match anywhere within the property name. For example, the regular expression "p" will match any property name with a p in it, such as "apple", not just a property whose name is simply "p". It’s therefore usually less confusing to surround the regular expression in ^...$, for example, "^p$".
for further reference --http://spacetelescope.github.io/understanding-json-schema/reference/object.html
Semantic of properties:
If you declare a property with a key included in properties, it must satisfy the schema declared in properties.
Semantic of patternProperties:
If you declare a property and the key satisfy the regex defined in patternProperties, it must satisfy the schema declared in patternProperties.
According to the docs, properties priority is higher than patternProperties, meaning that the schema is validated against patternProperties only if there has not been a match in properties first.
A JSON object is composed of key: value pairs. In a schema the key correspond to a property and for the value part we define it's data type and some other constratints.
Therefore the following schema
{
"type": "object",
"properties": {
"a": {
"type": "number"
}
}
will only validate a JSON object with the key "a" that is an object like {"a": 1}. An object like {"b": 1} won't validate
Meanwhile the patternProperties tag allows you to define properties using a regex. In this you basically don't need to define all the properties one after another. A use case of this will be for example if you don't know the name of the keys in advance but you know that all the keys match a certain pattern.
Hence your schema can validate {"a": 1} as well as {"b": 1}
The patternProperties tag does the job of an additionalProperties tag but in addition allows you to have a finer control on the keys
I have a JSON object passed into my REST API. I use a generic API Controller which specific API's inherit. Using JSON.NET, I'm attempting to determine the basic type (String, Integer, Boolean, etc) of the JSON data. Here's an example:
Public Overridable Function PostValue(<FromBody()> record As JObject)
For Each thing As KeyValuePair(Of String, JToken) In record
MsgBox(thing.Key & ": " & thing.Value.ToString & " (" & thing.Value.Type & ")")
Next
'do other stuff and return some other stuff...
End Function
Unfortunately, this is just returning string as the type for all of the JSON values. Is there a good method to parse the basic type of a JSON data member from the string value?
UPDATE
I understand that JSON, as Javascript, is always untyped - and I know that when JSON data is passed around, it's always as a JSON string (and hence, typed string). I guess I was wondering if JSON.NET (or any other library for this matter) had a means to dynamically determine the basic types of the data stored within this JSON string. For example (note: I know that parseType doesn't exist):
Json.ParseType("1") ' --> String
Json.ParseType(1) ' --> Integer
Json.ParseType("True") ' --> String
Json.ParseType(True) ' --> Boolean
Json.ParseType([1,2,3]) ' --> Array
'etc...
This is for a large part due to two factors.
First you are serializing data, not structure (types).
and Second, Javascript (and thus JSON) are type-less. [eg. alert(1.0 == '1.0'); will result in true).
In order to preserve type information you need to serialize the type information, and do something with it on the deserialization side.
example:
{
__type__id: 'Int32',
__type__name: 'String',
id: 5,
name: 'Joe'
}
I would avoid trying to guess at the type. Just because you can convert the id property value into an Int32 (via guessing) doesn't mean that the next object's id value will be an Int32. You must also be careful of values that contain numeric data in string format.. for example, international phone numbers: 011334998723 - if you were to convert that to an integer type, you'd lose the leading zero and completely change the meaning of the data.
json values are always strings. you could try to parse a json string into variables to determine type
I'm using the JSON-FRAMEWORK in objective C to parse a JSON object.
When I call [jsonString JSONValue], I get back a dictionary, but the keys aren't in the same order as the JSON Object I'm parsing. Is there anyway to keep this order the same?
In JSON objects, by definition, the order of the key-value pairs is not meaningful. The specification allows a JSON producer to permute them any way it want, even at random -- and does not require a parser to preserve the ordering. RFC 4627 says:
An object is an unordered collection of zero or more name/value
pairs, where a name is a string and a value is a string, number,
boolean, null, object, or array.
If you need the ordering to be preserved, what you have is not JSON, but a home-defined format that just happens to look superficially like JSON.