Skip to content

JPath

JPath is the language IMan uses to point into a JSON document, similar to XPath for XML. It appears wherever a screen asks for a path into JSON: the field paths of the JSON Reader and JSON Writer, a Webservice Lookup's return path, a behaviour's error message path and response paging path, and the token path of an OAuth setup.

If JSON itself is new to you, the Webservices page has a short primer, and this video is a clear introduction.

Syntax

Child elements

JSON nests data, either as an object inside an object or as an array of objects. You write each level of nesting as the property name followed by a slash, so /customer/first_name is the first_name property of the customer object. A leading slash is optional.

Where a path starts from depends on the screen. In the Reader and Writer a field's path is relative to its transaction, and a transaction's path is relative to its parent transaction. A Webservice Lookup's return path, and the paths on a Webservice Behaviour, are absolute from the root of the response.

Write a property name that contains a slash, a square bracket or a space in double quotes: /"order number"/id.

Arrays

To address an array, follow the property name with square brackets. What goes inside the brackets chooses the element.

In a transaction's path IMan assumes the node is an array, so you do not need the brackets there.

Index

An index picks one element by position. Indexes are 1-based: the first element is [1], the second [2], and [0] matches nothing. Empty brackets, [], are the default and pick the first element.

Path Result
arrayProperty[1] The first object or value
arrayProperty[2] The second object or value
arrayProperty[] The first object or value, using the default syntax

Query

You can instead choose an element by a condition on its properties, written inside the brackets. A query returns the first element that matches.

The form is [nodeName <operator> value], where the operator is = or !=. The value can be a string in single or double quotes, a number, true, false or null. The node name on the left can itself be a path, so a query can look inside a nested object.

Path Result
arrayProperty[id=12345] The first object with an id property of 12345
arrayProperty[name != 'a value'] The first object whose name is not "a value"
arrayProperty[customer/last_name='Orzolek'] The first object whose nested customer has that last name

Combine two or more conditions with and. Every condition must be true:

discount_codes[code='TENOFF' and amount != '0.00']/value

There is no or, and no comparison other than equal and not equal.

Example 1: the outermost value is an object

{
  "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 JPaths

Path Returns
/document/orders/order_number 1028, the order_number of the first order
/document/orders/customer/first_name Karen, from the first order's customer object
/line_items[]/quantity 1, the quantity of the first element of line_items
/line_items[2]/quantity 2, the quantity of the second element
/document/orders/taxes[type='state']/amount 2.23, the amount of the tax object whose type is state

A path used as a field must end at a value. discount_codes[] on its own is invalid as a field because it expands to an object, not a value. Restrict it with a query and continue to a property, as in note_attributes[name='colour']/value or discount_codes[amount != '0.00']/value.

Writer JPaths

Path Writes
/document/orders/order_number A document object containing an orders object containing an order_number property
/line_items[]/quantity A line_items array containing an object with a quantity property
/line_items[2]/quantity Invalid. An index cannot be used when writing
/document/orders/taxes[type='state']/amount Invalid. A query cannot be used when writing

Forcing an empty array

Sometimes you need to write an empty array. Use the empty array syntax in the path and enter null as the field's default value.

The JSON Writer field dialog with the JPath tier_prices followed by empty square brackets, and a Default Value of null. The help text beneath reads: the value to set if the field has no value. Leave empty to omit the field. Set to null to write a null.

Example 2: the outermost value is an array

Here the document is an array of three objects, so the path starts with the brackets and no property name.

[
  { "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 JPaths

Path Returns
[2]/shipmentCost 13.80, the shipmentCost of the second object
[serviceCode='dpd_wallet_parcel_saturday_1030']/otherCost 2.10, the otherCost of the object with that serviceCode
[]/serviceCode dpd_wallet_next_day, the serviceCode of the first object