The JSON Compare Delta Format

1. Introduction

A JSON Delta is a JSON file which describes the differences between two JSON files. The structure of the delta is similar to that of the inputs, but additional objects are introduced to describe changes.

A delta is also used as the changeset input to the graft operation and conformance to the format described here is required for successful graft operations.

This format is currently in beta test and as such is subject to change.

2. Format

The delta itself is an object which contains one child member with key: dx_deltaJSON.

The value of this member is an object itself containing four objects:

  • Key: dx_data_sets – the equality of the overall inputs, can have the value A=B indicating both documents are equal, or A!=B indicating there is at least one change between inputs.
  • Key: dx_deltaJSON_delta - stores the main heart of the delta, the data itself.
  • Key: dx_deltaJSON_type - stores the type of delta. Can have the value diff for a full-context delta, update for a changes-only delta, or graft when using Graft with Conflicts output.
  • Key: dx_deltaJSON_metadata - stores metadata of the operation performed.

2.1. Metadata

The dx_deltaJSON_metadata object itself contains two child members, with keys operation and parameters.

The value of operation is an object whose child members have keys type, input-format and output-format. These child members store the type of comparison (e.g. merge), format the data was transmitted (e.g. multi_part_uris for JSON transmitted via multi-part form data containing URIs to JSON files), and output format (can be either JSON or XML depending on format requested).

The value of parameters is an object whose child members store the parameters used for the operation. E.g., if the Word by Word parameter was set to true, it will contain a member with key wordbyword and value true.

3. Delta Objects

The primary object used to describe changes has a key of dx_delta.

This contains a child object with one or two members with keys "A" and/or "B" which refer to the two inputs of the comparison. The "A" and "B" values then contain the content which is unique to the corresponding input.

The dx_delta object is used at the point in the structure at which the difference is detected. In trivially simple cases this could be the root node of the JSON structure, otherwise it will typically be found inside an array or object.

There is also an object with key dx_delta_string used when Word by Word comparison is set to true. The dx_delta_string object contains an array of items comprising strings and dx_delta objects.

4. Delta Types

There are currently three types of delta – full contextchanges only, and graft conflicts.

4.1. Full Context

Contains all the data from both inputs. The original inputs can be extracted from this file.

4.2. Changes Only

Does not include unchanged content, where unchanged content is defined as map keys and values without change.

Unchanged root elements are always present in the result where child elements have been changed. Unchanged array items are represented by null to allow alignment.

Some unchanged elements are represented by an empty form where possible.

JSON ValuesUnchanged Representation
Arrayempty array - []
Objectempty object - {}
Stringempty string - ""
Numbervalue is preserved
Truevalue is preserved
Falsevalue is preserved
Nullvalue is preserved

In the case of the JSON input solely consisting of a single unchanged value where the value is preserved, the equality can be checked by checking the dx_data_sets member which will have the value A=B.

4.3. Graft Conflicts

When using Graft with conflicts Output Format, the result is returned in delta format with conflicts annotated in suitable delta elements.

5. Examples

5.1. dx_delta

Given the following inputs

Input AInput B
12

The change is represented by the following structure:

dx_deltaJSON_delta
{ "dx_delta": { "A": 1, "B": 2 } }

5.2. dx_delta_string

Given the following inputs

Input AInput B
This is a good example of Word by Word processing.This is a great example of Word by Word processing.

The outputs using different settings of the Word By Word parameter are as follows:

dx_deltaJSON_delta (with Word by Word = false)
{
  "dx_delta": {
    "A": "This is a good example of Word by Word processing.",
    "B": "This is a great example of Word by Word processing."
  }
}
dx_deltaJSON_delta (with Word by Word = true)
{
  "dx_delta_string": [
    "This is a ",
    {
      "dx_delta": {
        "A": "good",
        "B": "great"
      }
    },
    " example of Word by Word processing."
  ]
}

5.3. Full Delta

Using the inputs from the previous example a full delta file including meta data would be as follows:

Full Delta for the previous example (with Word by Word = false)
{
  "dx_deltaJSON": {
    "dx_data_sets": "A!=B",
    "dx_deltaJSON_type": "diff",
    "dx_deltaJSON_metadata": {
      "operation": {
        "type": "compare",
        "input-format": "multi_part_strings",
        "output-format": "JSON"
      },
      "parameters": {
        "wordbyword": false,
        "arrayalignment": "TYPE_WITH_VALUE_PRIORITY",
        "output": "FULL_CONTEXT"
      }
    },
    "dx_deltaJSON_delta": {
      "dx_delta": {
        "A": "This is a good example of Word by Word processing.",
        "B": "This is a great example of Word by Word processing."
      }
    }
  }
}

5.4. Full Context vs. Changes Only

With the following inputs

Input AInput B
[ 1, 2, 3 ][ 1, 9, 3 ]

The full context delta is as follows:

Full Context dx_deltaJSON_delta
[
  1,
  {
    "dx_delta": {
      "A": 2,
      "B": 9
    }
  },
  3
]

The changes only delta is as follows:

Changes Only dx_deltaJSON_delta
[
  null,
  {
    "dx_delta": {
      "A": 2,
      "B": 9
    }
  },
  null
]

5.5. Changes Only with Preserved Value

The input equality can be verified by checking the dx_data_sets member which has the value of A=B.

Input AInput B
truetrue

The full result is as follows:

Changes Only Delta
{
  "dx_deltaJSON": {
    "dx_data_sets": "A=B",
    "dx_deltaJSON_type": "update",
    "dx_deltaJSON_metadata": {
      "operation": {
        "type": "compare",
        "input-format": "multi_part_strings",
        "output-format": "JSON"
      },
      "parameters": {
        "wordbyword": false,
        "arrayalignment": "TYPE_WITH_VALUE_PRIORITY",
        "output": "CHANGES_ONLY"
      }
    },
    "dx_deltaJSON_delta": true
  }
}