Search code examples
javajsonjacksonjackson2

How to filter elements of json based on attribute values


I have a json schema with many elements with attribute "image".

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

and actual json looks like below

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

Is it possible to filgter schema based on attribute "image" and get list of all the elements in jsonpath format

$.a.b.c.passportPhoto

I have to read json using json path and then do something about photo like serialize it. but my question is about how to filter schema based on "image" attribute in Java system.


Solution

  • To do that you can use Jayway JsonPath library. It allows to find paths for given property. When you find all paths you can extract values for them. JSON Schema which describes JSON is also a valid JSON so firstly, you can extract all properties from JSON Schema and after that proces given JSON payload. In below example I use predefined list of properties.

    For given JSON payload (assume that all *photo properties are described in schema as images):

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

    Below example:

    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));
            }
        }
    }
    

    Prints:

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

    See also:

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