Is it possible to replace an item in the JSON array with the help of a pointer using Vert.x JSON Pointer?

1k Views Asked by At

While using Vert.x, for manipulating JSONs I'm using a JSON Pointer. Recently came across having to do the same with JSON arrays.

Here's the sample code I tried.

String jsonInput = "{\"string\":\"string\",\"json\":{\"items\":[\"item-1\",\"item-2\",\"item-3\"]}}";
JsonObject json = new JsonObject(jsonInput);
JsonPointer pointer = JsonPointer.from("/json/items/0");
System.out.println(pointer.writeJson(json,"new item"));

Consider this as the input

{
    "string": "string",
    "json": {
        "items": [
            "item-1",
            "item-2",
            "item-3"
        ]
    }
}

The pointer to item-1 would be /json/items/0. When I use the same with JsonPointer from Vert.x instead of replacing the existing item, it ends up adding another element instead of writing at index zero like below

{
    "string": "string",
    "json": {
        "items": [
            "<newly-written-item>"
            "item-1",
            "item-2",
            "item-3"
        ]
    }
}

Is it possible to overwrite the existing value instead of adding at the index ?

1

There are 1 best solutions below

1
On

I think it is not possible with writeJson() as it always adds the new element at the given index. In the implementation from vertx's repository you can see that vertx always uses the following method to write array elements, which can only add a new element:

public boolean writeArrayElement(Object value, int i, Object el) {
    if (isArray(value)) {
      try {
        ((JsonArray)value).getList().add(i, el);
        return true;
      } catch (IndexOutOfBoundsException e) {
        return false;
      }
    } else return false;
  }

For JsonObjects, vertx uses the following method, which will replace existing values:

  @Override
  public boolean writeObjectParameter(Object value, String key, Object el) {
    if (isObject(value)) {
      ((JsonObject)value).put(key, el);
      return true;
    } else return false;
  }

A possible workaround could be to query the JsonArray and manually replace the array element like this:

String jsonInput = "{\"string\":\"string\",\"json\":{\"items\":[\"items-1\",\"item-2\",\"item-3\"]}}";
JsonObject json = new JsonObject(jsonInput);
JsonPointer pointer = JsonPointer.from("/json/items");
JsonArray jsonArray = (JsonArray) pointer.queryJson(json);
jsonArray.remove(0);
jsonArray.add(0, "new item");

System.out.println(json);

Output:

{"string":"string","json":{"items":["new item","item-2","item-3"]}}