【问题标题】:How to filter elements of json based on attribute values如何根据属性值过滤json的元素
【发布时间】:2019-02-14 10:51:13
【问题描述】:

我有一个 json 架构,其中包含许多具有“图像”属性的元素。

  "passportPhoto": {
    "description": "Passport photo",
    "type": "string",
    "image": {
      "binaryEncoding": "base64"
    }
  },

实际的 json 如下所示

  "passportPhoto": "photo in base 64 encoded string format",

是否可以根据属性“image”过滤模式并以 jsonpath 格式获取所有元素的列表

$.a.b.c.passportPhoto

我必须使用 json 路径读取 json,然后对照片做一些事情,比如序列化它。 但我的问题是关于如何在 Java 系统中根据“图像”属性过滤架构

【问题讨论】:

  • 我不确定这是否可能直接。您需要阅读架构并找到所有具有 image 属性的属性。之后,您需要找到给定属性列表的所有节点。如果架构是常量,您可以手动提取这些属性,然后尝试查找预定义属性列表的所有节点。
  • 我没有固定的模式。有许多应用程序,并且都有不同的架构。但他们同意他们将发送所有在模式中标记为“图像”的图像。我相信很多人都会面临类似的问题。
  • 见我下面的例子。它适用于预定义的一组属性,但是使用此示例,您应该能够将其扩展为首先读取架构,然后使用您找到的 int schema 属性在JSON 有效负载中查找路径和值。
  • @MichałZiober 非常感谢。这真的很有帮助。我得到 Path: $['chip']['properties']['passportPhoto']['image'] 但我想要 $['chip']['passportPhoto'] 。

标签: java json jackson jackson2


【解决方案1】:

为此,您可以使用Jayway JsonPath 库。它允许查找给定属性的路径。当您找到所有路径时,您可以为它们提取值。描述JSONJSON Schema 也是有效的JSON,因此首先,您可以从JSON Schema 中提取所有属性,然后处理给定JSON 有效负载。在下面的示例中,我使用预定义的属性列表。

对于给定的JSON 有效负载(假设所有*photo 属性在架构中描述为图像):

{
  "map": {
    "photo": "map photo"
  },
  "person": {
    "data": {
      "photos": {
        "photo": "photo Base64",
        "passportPhoto": "passport photo Base64"
      }
    }
  }
}

下面的例子:

import com.jayway.jsonpath.EvaluationListener;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.ReadContext;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class JsonPathApp {
    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        List<String> paths = new ArrayList<>();
        ReadContext findPathsContext = JsonPath.parse(jsonFile).withListeners((found) -> {
            paths.add(found.path());
            return EvaluationListener.EvaluationContinuation.CONTINUE;
        });

        List<String> properties = Arrays.asList("photo", "passportPhoto");
        properties.forEach(p -> findPathsContext.read("$.." + p));

        ReadContext readContext = JsonPath.parse(jsonFile);

        for (String path : paths) {
            System.out.println("Path: " + path);
            System.out.println("Value: " + readContext.read(path));
        }
    }
}

打印:

Path: $['map']['photo']
Value: map photo
Path: $['person']['data']['photos']['photo']
Value: photo Base64
Path: $['person']['data']['photos']['passportPhoto']
Value: passport photo Base64

另见:

  1. Jsonpath with Jackson or Gson
  2. Json Path Maven

【讨论】:

  • 非常感谢。这几乎是我需要的。你能进一步帮助我吗我的架构是这样的“芯片”:{“类型”:“对象”,“属性”:{“芯片”:{“护照照片”:{“描述”:“护照照片”,“ type": "string", "image": { "binaryEncoding": "base64" } },我得到 Path: $['chip']['properties']['passportPhoto']['image'] 但我想要$['chip']['passportPhoto']
  • @SammyPawar,将['properties']['image'] 替换为EMPTY String,你会得到你想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-30
  • 2015-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多