IBM Integration Bus, Version 10.0.0.15 Operating Systems: AIX, HP-Itanium, Linux, Solaris, Windows, z/OS


Transforming heterogeneous JSON data in a message map

In the Graphical Data Mapping editor, you can use the Add User-Defined function to transform heterogeneous JSON data.

Before you begin

Create a message map with the output domain set to JSON. For more information, see Graphically modeling a JSON message in a message map

About this task

The approach for modeling JSON heterogeneous data is to define each structure as a union of the different data that can be present in each possible form. Then, set the data, which is present in some instances of the data, as optional.

By default, when you model JSON data in the Graphical Data Mapping editor, you create objects and arrays where all instances are the same. All objects with the same name have the same set of data fields, and all entities in an array have the same set of data fields. This use case matches the most common usage of JSON data formats.

JSON allows entries in JSON arrays to have different structure and types. For JSON Objects, some JSON applications may also allow the same name for contained objects or values which may then have different structure and types. The JSON specification states: "The names within an object SHOULD be unique." For more information, see The JavaScript Object Notation (JSON) Data Interchange Format). Only use this format if it is required by the external applications. This format of JSON data is termed heterogeneous JSON data.

If you have a JSON schema for your message data, you can use that as described in Creating or transforming a JSON message by using a JSON schema. Alternatively, you can model heterogeneous JSON data by using the Add User-Defined function as described in this topic, or you can use an equivalent XML schema model as described in Modeling a JSON message for use in a message map by using an equivalent XML schema model.

In the Graphical Data Mapping editor, the following rules apply when you model a heterogeneous JSON array:
  • All entries in the array must contain either objects or values.
  • You can model heterogeneous JSON data object arrays by using the Add User-Defined function.
  • To model heterogeneous JSON value arrays, where the type of each instance can vary, you must use an external schema to provide the type of the Item element that represents each value entry in the array.

Procedure

Complete the following steps to model heterogeneous JSON data in the Graphical Data Mapping editor:

  1. Build a union of the possible data fields, and set the elements that do not exist in every instance as optional.
    1. Use the Add User-Defined function to add user-defined elements to the map.
    2. In the Properties page of each element, configure the element's General tab to set the minimum occurrence to 0 so that the element is optional.

    Alternatively, you can use an external schema to provide the type of the Item element that represents each value entry in the array. The type can be defined as a schema union of simple types or an xsd:anySimpleType.

  2. To model a JSON object with the same named but different typed contained objects, add the object once and then set the maximum occurrence of its cardinality to indicate the number of occurrences. The single object is a union of the possible content.
  3. Use conditional mappings to read or construct the output data in each instance. For more information, see Choosing a transform to define a conditional mapping.

    When you map to a heterogeneous JSON value modeled as a union of possible types, you must ensure the input data or value that is returned from the transform is of the type that is required for the instance being set. You can use the xs:<type> cast functions to set the data type that is required.

Example

This example shows how to transform a JSON object message that describes a vehicle that uses two heterogeneous JSON data objects with different named values into a heterogeneous JSON array message where each entry is a data object with different named values.

The input application produces a heterogeneous JSON object message that describes a vehicle that uses two heterogeneous JSON data objects. Each JSON data object is called attribute and contains different name-value elements. The input JSON Data is as below:

{ "Description" : {
      "attribute"  : {
          "colour" : "blue",
          "metallic" : true
      },
      "attribute"  : {
          "capacity" : 1.4,
          "fuel" : "diesel"
      }
  }
}
In the map, the Description object is modeled with an attribute object that can occur twice (maximum occurrence set to be 2).
  • The heterogeneous attribute object contains the name - values colour and metallic or capacity and fuel.
  • Each of the name - values is modeled as optional (minimum occurrence set to be 1).

Shows the input message

The target application requires this information as a heterogeneous JSON array:
[{"attributeType":"Paint","colour":"blue","metallic":true},
{"attributeType":"Engine","capacity":1.4E+0,"fuel":"diesel"}]
In the map, the output JSON array is defined as the union of the possible data fields:
  • The array is represented by a JSON object of type Anonymous.
  • The first element is a single required element attributeType. All entries in the array contain this name-value.
  • The other name-value elements are colour, metallic, capacity, and fuel. These elements do not occur in all entities in the array. All these elements are defined as optional. Each element has its property minimum occurrence set to be 0.

Shows the output message

To transform from the input to the required output, you use the For Each transform to create each of the entries in the array from the same named (repeating) attribute input objects.

Shows the For each transform between the input and the output message

Inside the nested map associated with the For Each transform, you define an If transform that checks whether the attribute element contains colour or capacity.
  1. You define the If condition to check for colour: $attribute2/colour When this expression evaluates to true, the transformation in the nested map associated with the If is applied.
  2. The Else path does not require a condition. When the If expression evaluates to false, the transformation in the nested map associated with the Else is applied.

Shows the nested map of the Append transform between the input and the output message

The nested map that is associated to the If transform sets the attributeType element to Paint and copies the value of the other elements unchanged.

Shows the fist local map of the Append transform between the input and the output message

The other nested map that is associated to the Else sets the attributeType element to Engine and copies the value of the other elements unchanged.

Shows the second local map of the Append transform between the input and the output message

When you run this map, you get the following JSON message:
[{"attributeType":"Paint","colour":"blue","metallic":true},
{"attributeType":"Engine","capacity":1.4E+0,"fuel":"diesel"}]
You obtain the following output tree structure:
  
(0x01000000:Object):JSON       = ( ['json' : 0x298f1e00]
    (0x01001000:Array):Data = (
      (0x01000000:Object):Item = (
        (0x03000000:NameValue):attributeType = 'Paint' (CHARACTER)
        (0x03000000:NameValue):colour        = 'blue' (CHARACTER)
        (0x03000000:NameValue):metallic      = TRUE (BOOLEAN)
      )
      (0x01000000:Object):Item = (
        (0x03000000:NameValue):attributeType = 'Engine' (CHARACTER)
        (0x03000000:NameValue):capacity      = 1.4E+0 (FLOAT)
        (0x03000000:NameValue):fuel          = 'diesel' (CHARACTER)
      )
    )
  )

What to do next

Deploy the message map and verify that the output message is valid. For more information, see Troubleshooting a message map.


sm12026_.htm | Last updated 2018-12-15 07:47:29