Home > Software engineering >  How to conditionally extract a Json value using JayWay JsonPath?
How to conditionally extract a Json value using JayWay JsonPath?

Time:12-20

I have the following JSON:

{
   "A":{
      "C":{
         "date":"2022-01-23"
      }
   },
   "B":{
      "D":{
         "date":"2022-01-24"
      }
   }
}

I would like to extract the value $.A.C.date if it is not null, else I would like to extract $.B.D.date.

Basically I would like to write an if else expression using JsonPath. However, I don't manage to make it work.

This is what I've tried:

String expression = "$.[?($.[?(@.A.C.date != null)].date || $.[?(@.B.D.date != null)].date)]";
JsonPath jsonPath = JsonPath.compile(expression);
String json = "...my JSON...";
Object extractedValue = jsonPath.read(json);
System.out.println(extractedValue);

... but the output I get is simply an empty array: [].

I have also tried this:

"$.[?($.[?(@.A.C.date != null)].A.C.date || $.[?(@.B.D.date != null)].B.D.date)]"

... but the output is a list with all the elements (because conditions match in both cases), yet I thought that writing .A.C.date was extracting just the date and not everything:

[
    {"A":{"C":{"date":"2022-01-23"}},
    "B":{"D":{"date":"2022-01-24"}}}
]

Anyone has an idea? I can't find anything online which is similar to this.

This is the dependency I'm using:

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.4.0</version>
</dependency>

CodePudding user response:

Here is a possible solution using com.jayway.jsonpath

import com.jayway.jsonpath.JsonPath;

import java.util.List;

class Scratch {
    public static void main(String[] args) {
        JsonPath jsonPath = JsonPath.compile("$.*.*[?(@.date != \"null\")].date");
        List<String> read = jsonPath.read("{\n"  
                "   \"A\":{\n"  
                "      \"C\":{\n"  
                "         \"date\":\"2022-01-23\"\n"  
                "      }\n"  
                "   },\n"  
                "   \"B\":{\n"  
                "      \"D\":{\n"  
                "         \"date\":\"2022-01-24\"\n"  
                "      }\n"  
                "   }\n"  
                "}");
        System.out.println(read.get(0));
    }
}

It gets all the non-null dates then prints the first.

CodePudding user response:

You may consider another library Josson to do the job.

https://github.com/octomix/josson

Josson josson = Josson.fromJsonString(
    "{"  
    "   \"A\":{"  
    "      \"C\":{"  
    "         \"date\":\"2022-01-23\""  
    "      }"  
    "   },"  
    "   \"B\":{"  
    "      \"D\":{"  
    "         \"date\":\"2022-01-24\""  
    "      }"  
    "   },"  
    "   \"E\":{"  
    "      \"F\":{"  
    "         \"date\":null"  
    "      }"  
    "   }"  
    "}");
String date = josson.getString("coalesce(A.C.date, B.D.date)");
System.out.println(date);
date = josson.getString("coalesce(E.F.date, B.D.date)");
System.out.println(date);
date = josson.getString("*.*.date[isNotNull()]");
System.out.println(date);
date = josson.getString("*().date[isNotNull()]");
System.out.println(date);
JsonNode node = josson.getNode("**.**.date[isNotNull()]*");
System.out.println(node.toString());

Output

2022-01-23
2022-01-24
2022-01-23
2022-01-23
["2022-01-23","2022-01-24"]
  • Related