Skip to content

Adding support for multiple selection/update #23

Open
@geryogam

Description

@geryogam

A core feature that is missing in JSON Pointer/JSON Patch specifications in my opinion is the ability to select/update multiple array or object items with a single path expression.

It would for instance solve issue #21 elegantly.

Motivation

Before knowing about JSON Pointer/JSON Patch, I developed a Python tool to update a few hundreds of JSON at work. I chose a JSON Patch-like approach. For selecting the nodes of JSON documents, I did not want to write my own path expression parser so I used Kenn Knowles’ JSON Path RW Python library that implements Stefan Goessner’s JSON Path specification (which has no official RFC at the moment). And it worked quite well for our needs.

The main reason why I based my tool on JSON Path was because it allows for multiple selection of array or object items. And the alternative of using multiple patch operations on single items was not an option, as the array and object sizes were not known in advance (they were different for each JSON document). So rebasing my tool on JSON Pointer instead of JSON Path for path expressions is currently not possible.

Examples

Here are two examples of what could be achieved by adding support for

  • array slice expressions start:end:step (e.g., ::2 matches all even array indexes);
  • object globbing expressions with wildcards *, ? and […] (e.g., *ing matches all object keys ending with ‘ing’)

in path expressions of JSON Pointer/JSON Patch.

I have used the add operator but array slice and object globbing should also work with the other operators of course (remove, replace, move, etc.).

Array slice

Target JSON document:

[
  {"foo": "bar"},
  {"foo": "bar"},
  {"foo": "bar"}
]

Patch JSON document:

[
  {"op": "add", "path": "/:/baz", "value": "qux"}
]

Resulting JSON document:

[
  {"foo": "bar", "baz": "qux"},
  {"foo": "bar", "baz": "qux"},
  {"foo": "bar", "baz": "qux"}
]

Object globbing

Target JSON document:

{
  "a": {"foo": "bar"},
  "b": {"foo": "bar"},
  "c": {"foo": "bar"}
}

Patch JSON document:

[
  {"op": "add", "path": "/*/baz", "value": "qux"}
]

Resulting JSON document:

{
  "a": {"foo": "bar", "baz": "qux"},
  "b": {"foo": "bar", "baz": "qux"},
  "c": {"foo": "bar", "baz": "qux"}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions