JPath

To query and access elements within a JSON document we have created a language which is in similar nature to XPath, the language used to query an Xml document.

A quick search on Youtube will yield several good introductions on JSON. The clearest and easiest to digest is the following...

https://www.youtube.com/watch?v=iiADhChRriM

Syntax

Child Elements

Similarly to Xml, one of the fundamental aspects of JSON is the nesting of data elements either as a nested object or as a collection (or array) of objects.

Each level of nesting either of objects or arrays requires the name of the property followed by a slash.

When working in the Reader or Writer the JPath's are relative to current transaction in the case of a field or the parent transaction in case of a transaction, whereas the Webservice Lookup will use an absolute path. See relevant sections on discussion.

Collections/Arrays

To access an array the property name is followed by an opening and closing square brackets.

If used in a JPath for the transaction, it is assumed the node being access is an array and thus there is no need to use the array identifier.

Index

You can access the elements using an index or to access the first object/element in the array you can use the default syntax []. Arrays are 1 based, so the first element starts at 1 and second 2, and so on.

arrayProperty[1] - Access the first object/value

arrayProperty[2] - Access the second object/value

arrayProperty[] - Access the first object/value using the default syntax.

Query

Nodes with an array may also be accessed via a node query. The query is enclosed in a square brackets where the query refers to properties within each of the array's objects.

The query syntax is of form:

nodeName <operand> value

IMan's supports the equals (=) and not equals (!=) operands.

arrayProperty[id=12345] - Matches the first object where there is an id property with the value of 12345.

arrayProperty[name != 'a value'] - Matches the first object where the name does not equal "a value".

Example #1 - object is outermost value


{
  "document": {
    "orders": [
      {
        "order_number": "1028",
        "token": "3b26b5ecd992012ac7a5e609f2d3379e",
        "email": "[email protected]",
        "customer": {
          "first_name": "Karen",
          "last_name": "Orzolek"
        },
        "taxes": [
          {
            type: "local",
            jurisdiction: "brooklyn",
            amount: 0.45
          },
          {
            type: "state",
            jurisdiction: "NY",
            amount: 2.23
          },
          {
            type: "federal",
            jurisdiction: "NA",
            amount: 1.10
          }
        ],
        "line_items": [
          {
            "sku": "A1-103/0",
            "description": "Gold Leggings",
            "quantity": 1,
            "price": 10.22
          },
          {
            "sku": "A1-401/0",
            "description": "1000 Shiny Sequins",
            "quantity": 2,
            "price": 20.44
          }
        ]
      },
      {
        "order_number": "1022",
        "token": "c174903a6021d459308832185b93f9d3",
        "email": "[email protected]",
        "customer": {
          "first_name": "Ricardo",
          "last_name": "Villalobos"
        },
        "taxes": [
          {
            type: "local",
            jurisdiction: "berlin",
            amount: 0.45
          }
        ],
        "line_items": [
          {
            "description": "Assorted Microhouse",
            "quantity": 3,
            "price": 12.75
          }
        ]
      }
    ]
  }
}

Reader JPath's

  • /document/orders/order_number
    • Returns 1208 - The value from the order_number property from the first order.
  • /document/orders/customer/first_name
    • Returns "Karen" - The value from the 'first_name' property from the first 'order'.
  • /line_items[]/quantity
    • Returns 1 - The 'quantity' value of the first element in the line_items array.
  • /line_items[2]/quantity
    • Returns 2 - The 'quantity' value of the second element in the line_items array.
  • /document/orders/taxes[type='state']/amount
    • Returns 2.23 - Returns the 'amount' from tax object where the object has a type property with the value 'state'.
  • INVALID – discount_codes[] – Expands to an object and not a set of values.
    • Allow a simple equal or not-equal expression within a set of square brackets to allow you to specify restrict properties.
    • Example - note_attributes[name=’colour’]/value
    • Example - discount_codes[amount != ‘0.00’]/value
    • INVALID - discount_codes[code=’TENOFF’ and amount != ‘0.00’]/value

Writer JPath's

/document/orders/order_number

  • Writes - Creates an object of 'document's, then an object 'orders', then an 'order_number' property

/line_items[]/quantity

  • Writes - Creates an array 'line_items' where an object will be nested where that object will have a 'quantity' property.

/line_items[2]/quantity

  • INVALID - You cannot specify indexes on arrays when writing JSON data.

/document/orders/taxes[type='state']/amount

  • INVALID - You cannot specific array queries when writing JSON data.

Forcing an empty array

It is sometimes necessary to write an empty array. Use the empty array syntax in the path AND enter null as the default value for the JPath.

/prices[]

Example #2 - Outermost value is array

This example shows three objects nested within an array. Whereas Example #1 has an object as the outermost value this example has an array as an outermost value.


[
  {
    "serviceName": "dpd",
    "serviceCode": "dpd_wallet_next_day",
    "shipmentCost": 6.59,
    "otherCost": 0.0
  },
  {
    "serviceName": "dpd",
    "serviceCode": "dpd_wallet_parcel_saturday_1200",
    "shipmentCost": 13.80,
    "otherCost": 0.0
  },
  {
    "serviceName": "dpd",
    "serviceCode": "dpd_wallet_parcel_saturday_1030",
    "shipmentCost": 20.70,
    "otherCost": 2.10
  }
]

Reader JPath's

  • [2]/shipmentCost
    • Returns 13.80 - The value from shipmentCost property from the second object.
  • [serviceCode = 'dpd_wallet_parcel_saturday_1030']/otherCost
    • Returns 2.10 - The value from otherCost property where the object has a 'serviceCode' property with the value of 'dpd_wallet_parcel_saturday_1030'.
  • []/serviceCode
    • Returns 'dpd_wallet_next_day' - The value from serviceCode property from the first object.