Search code examples
javajsonfasterxml

How do I get the full path of everywhere a JSON field occurs using FasterXML?


Given a JSON field name such as "my_field" and a FasterXML JSON ObjectNode, how can I walk through the JSON and get the fully qualified path of everywhere that "my_field" occurs in the JSON?

"top_field": {
        "mid_field": [
            {
                "my_field": true,
            },
            {
                "my_field": true,
            }
        ],
        "another_mid_field": [
            {
                "my_field": false
            }
        ]
    }

I would want to have the following results:

 top_field.mid_field[0].my_field
 top_field.mid_field[1].my_field
 top_field.another_mid_field.my_field

Is there a part of the FasterXML library that exposes this information without having to parse all the values of the JSON? I was previously using recursion to do so, starting from the root top_field and walking down, passing each object down as I went but that is prone to stack overflows on large JSON objects.


Solution

  • This main:

    package jsonpath;
    
    import java.util.List;
    
    import com.jayway.jsonpath.Configuration;
    import com.jayway.jsonpath.Option;
    import static com.jayway.jsonpath.JsonPath.*;
    
    public class GetPaths {
    
        public static void main(String [] args) {
            String json = "{\"top_field\": { \"mid_field\": [ { \"my_field\": true, }, { \"my_field\": true, } ], \"another_mid_field\": [ { \"my_field\": false } ] }}";
    
            Configuration conf = Configuration.builder().options(Option.AS_PATH_LIST).build();
            List<String> pathList = using(conf).parse(json).read("$..my_field");
            for(String path : pathList) {
                System.out.println(path);
            }
        }
    }
    

    Will output exactly

    $['top_field']['mid_field'][0]['my_field']
    $['top_field']['mid_field'][1]['my_field']
    $['top_field']['another_mid_field'][0]['my_field']
    

    If you do some simple string replace on that one I think it´s a nice and easy solution. I`m not sure if you can get anything similar with plain Jackson/FasterXML. JsonPath uses Jackson under the hood.