如何使用 Jackson 递归修改 JsonNode 的值 [英] How to modify the value of a JsonNode recursively using Jackson

查看:132
本文介绍了如何使用 Jackson 递归修改 JsonNode 的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要求:
我想对 JsonNode 的内部值应用一些函数.函数可以不同,例如:- lowercasing 某些值或将某些内容附加到这些值或用某些内容替换这些值.我如何使用 Jackson 库实现这一目标?请注意,JSON 数据的结构可能不同,这意味着我想构建一个通用系统,该系统将接受一些路径表达式,这将基本上决定在哪里更改.我想使用函数式编程风格,以便我可以将这些函数作为参数传递.

Requirements:
I want to apply some functions on the inner values of the JsonNode. The functions can be different eg:- lowercasing some values or appending something to the values or replace the values with something. How can I achieve that using Jackson library? Note that the structure of the JSON data can be different which means I want to build a generic system which will accept some path expression which will basically decide where to change. I want to use functional programming style, so that I can pass these functions as arguments.

例如:

输入:

{
  "name": "xyz",
  "values": [
    {
      "id": "xyz1",
      "sal": "1234",
      "addresses": [
        {
          "id": "add1",
          "name": "ABCD",
          "dist": "123"
        },
        {
          "id": "add2",
          "name": "abcd3",
          "dist": "345"
        }
      ]
    },
    {
      "id": "xyz2",
      "sal": "3456",
      "addresses": [
        {
          "id": "add1",
          "name": "abcd",
          "dist": "123"
        },
        {
          "id": "add2",
          "name": "XXXXX",
          "dist": "345"
        }
      ]
    }
  ]
}

在这种情况下,我基本上必须使用两个函数,lowercase()convert_to_number().我想在每个 "value" 的所有 "addresses" 内的所有 "name" 属性上应用 lowercase() 函数.convert_to_number() 也是如此,但对于所有 "dist" 属性.

In this case I have to two functions basically, lowercase() and convert_to_number(). I want to apply lowercase() function on all the "name" attribute inside all the "addresses" of each "value". same goes for convert_to_number() , but for all the "dist" attribute.

所以,对于函数来说,JSON 表达式基本上如下所示:

So, basically the JSON expressions will be something like below for the functions:

lowercase() : /values/*/addresses/*/name
convert_to_number() : /values/*/addresses/*/dist

输出:

{
  "name": "xyz",
  "values": [
    {
      "id": "xyz1",
      "sal": "1234",
      "addresses": [
        {
          "id": "add1",
          "name": "abcd",
          "dist": 123
        },
        {
          "id": "add2",
          "name": "abcd3",
          "dist": 345
        }
      ]
    },
    {
      "id": "xyz2",
      "sal": "3456",
      "addresses": [
        {
          "id": "add1",
          "name": "abcd",
          "dist": 123
        },
        {
          "id": "add2",
          "name": "xxxx",
          "dist": 345
        }
      ]
    }
  ]
}

客户端代码:

JsonNode jsonNode = ...
applyFunctionsRecursivelyBasedOnExpr(JsonNode jsonNode, String expr, Function )

推荐答案

正如@MichalZiober 在他的回答中已经指出的那样,JsonPath 提供了比 Jackson 更强大的 API,当您需要执行基于 JSON 路径的操作时.

As @MichalZiober in his answer already pointed out, JsonPath offers a much more powerful API than Jackson, when you need to do JSON-path-based operations.

使用方法 JsonPath.parse<代码>WriteContext.map您只需几行即可解决您的问题:

Using methods JsonPath.parse and WriteContext.map you can solve your problem in just a few lines:

import java.io.File;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;

public class Main {

    public static void main(String[] args) throws Exception {
        File file = new File("input.json");
        String json = JsonPath.parse(file)
                .map("$.values[*].addresses[*].name", Main::lowerCase)
                .map("$.values[*].addresses[*].dist", Main::convertToNumber)
                .jsonString();
        System.out.println(json);
    }

    private static Object lowerCase(Object currentValue, Configuration configuration) {
        if (currentValue instanceof String)
            return ((String)currentValue).toLowerCase();
        return currentValue;
    }

    private static Object convertToNumber(Object currentValue, Configuration configuration) {
        if (currentValue instanceof String)
            return Integer.valueOf((String)currentValue);
        return currentValue;
    }
}

这篇关于如何使用 Jackson 递归修改 JsonNode 的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆