This version of the specification introduced significant optimizations to the JSON encoding, however, there are existing products that support the deprecated JSON encoding. This Annex summarizes the differences and explains how a product can be designed to seamlessly support the deprecated and current versions of the JSON encoding.
The ReversibleEncoding is largely the same as the CompactEncoding. The NonReversibleEncoding is largely the same as the to the VerboseEncoding. The differences are described in the rest of this Annex.
Any product that supports the OpenAPI mappings defined in G.3 only supports the CompactEncoding. The deprecated encodings published earlier versions of this specification are only used by older products implementing MQTT mapping for PubSub defined in OPC 10000-14.
The expectation is all encoders used for Publishers support all four encodings and all decoders for Subscribers support the ReversibleEncoding, CompactEncoding and VerboseEncodings.
NodeId values shall be encoded as a JSON object with the fields defined in Table H.1.
Decoders that support the deprecated encodings use the JSON datatype to detect which encoding is used. A JSON string is the current encoding; a JSON object means it is the deprecated encoding.
Table H.1 – JSON Object Definition for a NodeId
Name |
Description |
IdType |
The IdentifierType encoded as a JSON number. Allowed values are: 0 - UInt32 identifier encoded as a JSON number. 1 - A String identifier encoded as a JSON string. 2 - A Guid identifier encoded as described in 5.4.2.7. 3 - A ByteString identifier encoded as described in 5.4.2.8. This field is omitted for UInt32 identifiers. |
Id |
The identifier. The value of the IdType field specifies the encoding of this field. |
Namespace |
This field is a JSON number with the NamespaceIndex. The field is omitted if the NamespaceIndex is 0. For NonReversibleEncoding this field is the JSON string containing the NamespaceUri associated with the NamespaceIndex unless the NamespaceIndex is 0. If the NamespaceIndex is 0 the field is omitted. |
ExpandedNodeId values shall be encoded as a JSON object with the fields defined in Table H.2.
Decoders that support the deprecated encodings use the JSON datatype to detect which encoding is used. A JSON string is the current encoding; a JSON object means it is the deprecated encoding.
Table H.2 – JSON Object Definition for an ExpandedNodeId
Name |
Description |
IdType |
The IdentifierType encoded as a JSON number. Allowed values are: 0 - UInt32 Identifier encoded as a JSON number. 1 - A String Identifier encoded as a JSON string. 2 - A Guid Identifier encoded as described in 5.4.2.7. 3 - A ByteString Identifier encoded as described in 5.4.2.8. This field is omitted for UInt32 identifiers. |
Id |
The Identifier. The value of the IdType field specifies the encoding of this field. |
Namespace |
For ReversibleEncoding this field is a JSON string with the NamespaceUri if the NamespaceUri is specified. Otherwise, it is a JSON number with the NamespaceIndex. The field is omitted if the NamespaceIndex is 0. For NonReversibleEncoding this field is the JSON string containing the NamespaceUri or the NamespaceUri associated with the NamespaceIndex unless the NamespaceIndex is 0 or 1. If the NamespaceIndex is 0 the field is omitted. |
ServerUri |
For ReversibleEncoding this field is a JSON number with the ServerIndex. The field is omitted if the ServerIndex is 0. For NonReversibleEncoding this field is the JSON string containing the ServerUri associated with the ServerIndex unless the ServerIndex is 0. If the ServerIndex is 0 the field is omitted. |
StatusCode values shall be encoded as a JSON number for the ReversibleEncoding. If the StatusCode is Good (0) it is only encoded if it is an element of a JSON array.
For the NonReversibleEncoding, StatusCode values shall be encoded as a JSON object with the fields defined in Table H.3.
Table H.3 – JSON Object Definition for a StatusCode
Name |
Description |
Code |
The numeric code encoded as a JSON number. The Code is omitted if the numeric code is 0 (Good). |
Symbol |
The string literal associated with the numeric code encoded as JSON string. e.g. 0x80AB0000 has the associated literal “Bad_InvalidArgument”. The Symbol is omitted if the numeric code is 0 (Good). If the string literal is not known to the encoder the field is omitted. |
For the NonReversibleEncoding, a StatusCode of Good (0) it is only encoded if it is an element JSON array.
The CompactEncoding and VerboseEncoding use the same JSON object as the NonReversibleEncoding. The CompactEncoding always omits the Symbol.
QualifiedName values shall be encoded as a JSON object with the fields shown in Table H.4.
Decoders that support the deprecated encodings use the JSON datatype to detect which encoding is used. A JSON string is the current encoding; a JSON object means it is the deprecated encoding.
Table H.4 – JSON Object Definition for a QualifiedName
Name |
Description |
Name |
The Name component of the QualifiedName. |
Uri |
For ReversibleEncoding this field is a JSON number with the NamespaceIndex. The field is omitted if the NamespaceIndex is 0. For NonReversibleEncoding this field is the JSON string containing the NamespaceUri associated with the NamespaceIndex unless the NamespaceIndex is 0. If the NamespaceIndex is 0 the field is omitted. |
For the ReversibleEncoding, LocalizedText values shall be encoded as a JSON object with the fields shown in Table H.5.
Table H.5 – JSON Object Definition for a LocalizedText
Name |
Description |
Locale |
The Locale portion of LocalizedText values shall be encoded as a JSON string |
Text |
The Text portion of LocalizedText values shall be encoded as a JSON string. |
For the NonReversibleEncoding, LocalizedText value shall be encoded as a JSON string containing the Text component.
Decoders that support the NonReversibleEncoding use the JSON datatype to detect which encoding is used. A JSON object is the current encoding; a JSON string means it is the NonReversibleEncoding.
For the ReversibleEncoding, ExtensionObject values shall be encoded as a JSON object with the fields shown in Table H.6.
Table H.6 – JSON Object Definition for an ExtensionObject
Name |
Description |
TypeId |
The NodeId of a DataTypeEncoding Node or a DataType Node formatted using the rules in H.2. |
Encoding |
The format of the Body field encoded as a JSON number. This value is 0 if the body is Structure encoded as a JSON object. This value is 1 if the body is a ByteString value encoded as a JSON string. This value is 2 if the body is a XmlElement value encoded as a JSON string. This field is omitted if the value is 0. |
Body |
Body of the ExtensionObject. The type of this field is specified by the Encoding field. If the Body is empty, the ExtensionObject is NULL and is omitted or encoded as a JSON null. |
For the NonReversibleEncoding, ExtensionObject values shall be encoded as a JSON value containing only the value of the Body field. The TypeId and Encoding fields are dropped.
Decoders that support the NonReversibleEncoding need to have out of band knowledge of the encoded Structure or treat the value as a generic JSON object.
For the ReversibleEncoding, Variant values shall be encoded as a JSON object with the fields shown in Table H.7.
Table H.7 – JSON Object Definition for a Variant
Name |
Description |
Type |
The Built-in type for the value contained in the Body (see Table 1) encoded as JSON number. If type is 0 (NULL) the Variant contains a NULL value and the containing JSON object shall be omitted or replaced by the JSON literal ‘null’ (when an element of a JSON array). |
Body |
If the value is a scalar, it is encoded using the rules for type specified for the Type. If the value is a one-dimensional array it is encoded as JSON array (see H.9). Multi-dimensional arrays are encoded as a one-dimensional JSON array which is reconstructed using the value of the Dimensions field (see 5.2.2.16). |
Dimensions |
The dimensions of the array encoded as a JSON array of JSON numbers. The Dimensions are omitted for scalar and one-dimensional array values. |
For the NonReversibleEncoding, Variant values shall be encoded as a JSON value containing only the value of the Body field. The Type and Dimensions fields are dropped. Multi-dimensional arrays are encoded as a multi-dimensional JSON array as described in H.9.
Decoders that support the NonReversibleEncoding need to have out of band knowledge of value encoded in the Variant or treat the value as a generic JSON object.
One dimensional Arrays shall be encoded as JSON arrays.
If an element is NULL, the element shall be encoded as the JSON literal ‘null’.
Otherwise, the element is encoded according to the rules defined for the type.
In the deprecated encodings, Multi-dimensional Arrays are encoded as nested JSON arrays. The outer array is the first dimension and the innermost array is the last dimension. For example, the following matrix
0 2 3 |
1 3 4 |
is encoded in JSON as
[[0, 2, 3], [1, 3, 4]]
The current encoding defines a JSON object for multi-dimensional Arrays. Decoders that support the deprecated encodings use the JSON datatype to detect which encoding is used. A JSON object means it is the current encoding; a JSON array means it is the deprecated encoding.
Encoders that support the deprecated encoding rely on a switch set by the application that controls which encoding is emitted.
Unions shall be encoded as JSON objects as shown in Table H.8 for the ReversibleEncoding.
Note that JSON objects are unordered sets of name-value pairs. The order specified by the DataTypeDefinition is not preserved when a Union is serialized in JSON. The SwitchField may not appear as the first field.
Table H.8 – JSON Object Definition for a Union
Name |
Description |
SwitchField |
The identifier for the field in the Union which is encoded as a JSON number. The valid values for this field follow the conventions defined in 5.2.8. If the SwitchField value is its DefaultValue of 0, then the SwitchField and the Value field are not present. |
Value |
The value of the field encoded using the rules that apply to the data type. |
For the NonReversibleEncoding, Union values are encoded using the rule for the current value. If the SwitchField is 0 the Union is encoded as a JSON null value.
For example, instances of the union:
struct Union1
{
Byte Selector;
{
Int32 A;
Double B;
Char* C;
}
Value;
};
would be represented in the ReversibleEncoding as:
{ "SwitchField":2, "Value":3.1415 }
In the NonReversibleEncoding, it is represented as:
3.1415
The CompactEncoding is the same as the ReversibleEncoding. The VerboseEncoding always has a JSON object with a name and value for the active field, however, the NonReversibleEncoding only encodes the value.
___________