このように構造化されたJSONがあるとします。
{
"name":"Some Guy",
"emails":[
{
"description":"primary",
"status":"UNVERIFIED",
"email":"[email protected]"
},
{
"description":"home",
"status":"VERIFIED",
"email":"[email protected]"
},
{
"description":"away",
"status":"VERIFIED",
"email":"[email protected]"
}
]
}
JSONPath式 にステータスVERIFIED
のfirstメールを取得し、ない場合は、次に、配列の最初のメールを取得します。したがって、上記の例の場合、結果は[email protected]
。この例を考えると:
{
"name":"Some Guy",
"emails":[
{
"description":"primary",
"status":"UNVERIFIED",
"email":"[email protected]"
},
{
"description":"home",
"status":"UNVERIFIED",
"email":"[email protected]"
}
]
}
これはJSONPath式で可能ですか?
実際には2つのJSONPath式があり、2番目の式(最初の電子メール)は最初の式(最初の検証済み電子メール)が何も返さない場合にのみ評価する必要があるため、1つで両方を同時に評価することはできないと思います式。
ただし、次々に適用できます。
_public static String getEmail(String json) {
Configuration cf = Configuration.builder().options(Option.SUPPRESS_EXCEPTIONS).build();
DocumentContext ctx = JsonPath.using(cf).parse(json);
List<String> emails = ctx.read("$.emails[?(@.status == 'VERIFIED')].email");
if (!emails.isEmpty()) {
return emails.get(0);
}
return ctx.read("$.emails[0].email");
}
_
電子メール配列が空の場合、 option _SUPPRESS_EXCEPTIONS
_のおかげで、ctx.read("$.emails[0].email")
は例外をスローする代わりにnullを返します。
パスの数が事前にわからない場合:
_public static String getEmail(String json, String[] paths) {
Configuration cf = Configuration.builder().options(Option.ALWAYS_RETURN_LIST, Option.SUPPRESS_EXCEPTIONS).build();
DocumentContext ctx = JsonPath.using(cf).parse(json);
for (String path : paths) {
List<String> emails = ctx.read(path);
if (!emails.isEmpty()) {
return emails.get(0);
}
}
return null;
}
_
オプション _ALWAYS_RETURN_LIST
_は、結果が1つまたは0の場合でも、戻り値の型がリストであることを意味します。
このコードはあなたのために完全に機能するはずです
//Use the json parsing library to extract the data
JsonPath jp = new JsonPath(json);
Map<String, Object> location = jp.get("name.emails[0]");
System.out.println(location);