0

how to use Jsonpath to set values with a customized function for nested JSON objects the JSON objects is nested by unordered json array and json object such as

{
    "store": {
       "name": "ABC Co",
        "book": [
            {
                "category": "reference",
                "author": "Nigel Rees",
                "title": "Sayings of the Century",
                "price": 8.95,
                "edition": {
                       "year": 1990,
                       "published_by": "MacMillan"
                 }
            },
            {
                "category": "fiction",
                "author": "Evelyn Waugh",
                "title": "Sword of Honour",
                "price": 12.99,
                "edition": {
                       "year": 1980,
                       "published_by": "MacMillan"
                 }
            }
        ]
     }
}

give any JsonPath such as $.store.book[0:].price (jsonarray) $.store.name (jsonobject) I want to use my own customized function such as encrypt function to process all the value matched by the provided jsonpath

Do any JsonPath package or library provide the function? Or how could I write the setNestedJson(String jsonPath, function func)

sincerely thanks for help!

I use com.alibaba.fastjson2.JSONPath, but it may be not able to set value with function.

for example

JSONPath.set(jsonobject, "$.store.book[0:].price", "test")

I wonder how to deal it with function

1 Answers1

0

You may try library Josson to flatten the JSON, change the required value, and then unflatten back.

https://github.com/octomix/josson

Deserialization

Josson josson = Josson.fromJsonString(
    "{" +
    "    \"store\": {" +
    "       \"name\": \"ABC Co\"," +
    "        \"book\": [" +
    "            {" +
    "                \"category\": \"reference\"," +
    "                \"author\": \"Nigel Rees\"," +
    "                \"title\": \"Sayings of the Century\"," +
    "                \"price\": 8.95," +
    "                \"edition\": {" +
    "                       \"year\": 1990," +
    "                       \"published_by\": \"MacMillan\"" +
    "                 }" +
    "            }," +
    "            {" +
    "                \"category\": \"fiction\"," +
    "                \"author\": \"Evelyn Waugh\"," +
    "                \"title\": \"Sword of Honour\"," +
    "                \"price\": 12.99," +
    "                \"edition\": {" +
    "                       \"year\": 1980," +
    "                       \"published_by\": \"MacMillan\"" +
    "                 }" +
    "            }" +
    "        ]" +
    "     }" +
    "}");

Demo of flatten()

JsonNode node = josson.getNode("flatten('_')");
System.out.println("Style 1:\n" + node.toPrettyString());
node = josson.getNode("flatten('.','[%d]')");
System.out.println("Style 2:\n" + node.toPrettyString());

Output

Style 1:
{
  "store_name" : "ABC Co",
  "store_book_0_category" : "reference",
  "store_book_0_author" : "Nigel Rees",
  "store_book_0_title" : "Sayings of the Century",
  "store_book_0_price" : 8.95,
  "store_book_0_edition_year" : 1990,
  "store_book_0_edition_published_by" : "MacMillan",
  "store_book_1_category" : "fiction",
  "store_book_1_author" : "Evelyn Waugh",
  "store_book_1_title" : "Sword of Honour",
  "store_book_1_price" : 12.99,
  "store_book_1_edition_year" : 1980,
  "store_book_1_edition_published_by" : "MacMillan"
}
Style 2:
{
  "store.name" : "ABC Co",
  "store.book[0].category" : "reference",
  "store.book[0].author" : "Nigel Rees",
  "store.book[0].title" : "Sayings of the Century",
  "store.book[0].price" : 8.95,
  "store.book[0].edition.year" : 1990,
  "store.book[0].edition.published_by" : "MacMillan",
  "store.book[1].category" : "fiction",
  "store.book[1].author" : "Evelyn Waugh",
  "store.book[1].title" : "Sword of Honour",
  "store.book[1].price" : 12.99,
  "store.book[1].edition.year" : 1980,
  "store.book[1].edition.published_by" : "MacMillan"
}

Expression to flatten, update values and unflatten on style 1

JsonNode node = josson.getNode(
    "flatten('_')" +
    ".field(store_book_0_price:9.99, store_book_1_price:19.00)" +
    ".unflatten('_')");
System.out.println(node.toPrettyString());

Expression to flatten, update values and unflatten on style 2

node = josson.getNode(
    "flatten('.','[%d]')" +
    ".field(store.book[0].price:9.99, store.book[1].price:19.00)" +
    ".unflatten('.[]')");
System.out.println(node.toPrettyString());

Output

{
  "store" : {
    "name" : "ABC Co",
    "book" : [ {
      "category" : "reference",
      "author" : "Nigel Rees",
      "title" : "Sayings of the Century",
      "price" : 9.99,
      "edition" : {
        "year" : 1990,
        "published" : {
          "by" : "MacMillan"
        }
      }
    }, {
      "category" : "fiction",
      "author" : "Evelyn Waugh",
      "title" : "Sword of Honour",
      "price" : 19.0,
      "edition" : {
        "year" : 1980,
        "published" : {
          "by" : "MacMillan"
        }
      }
    } ]
  }
}
Raymond Choi
  • 1,065
  • 2
  • 7
  • 8