JSONPath 表达式根据条件从数组中获取值或仅获取第一个值
JSONPath expression to get a value from an array on condition or just the first value
给定 JSON 结构如下:
{
"name":"Some Guy",
"emails":[
{
"description":"primary",
"status":"UNVERIFIED",
"email":"first@first-email.com"
},
{
"description":"home",
"status":"VERIFIED",
"email":"second@second-email.com"
},
{
"description":"away",
"status":"VERIFIED",
"email":"third@third-email.com"
}
]
}
我想要 JSONPath expression 获取状态为 VERIFIED
的 第一个 电子邮件,如果有 none,则只需获取数组中的第一封电子邮件。因此,根据上面的示例,结果将是 second@second-email.com
。给出这个例子:
{
"name":"Some Guy",
"emails":[
{
"description":"primary",
"status":"UNVERIFIED",
"email":"first@first-email.com"
},
{
"description":"home",
"status":"UNVERIFIED",
"email":"second@second-email.com"
}
]
}
结果将是 first@first-email.com
。
JSON路径表达式是否可行?
你实际上有 2 个 JSONPath 表达式,其中第二个(第一封电子邮件)只有在第一个(第一封经过验证的电子邮件)return什么都没有的情况下才应该被评估,所以我认为你无法评估它们同时出现在一个表达式中。
不过,您可以一个接一个地应用它们:
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");
}
如果电子邮件数组为空,ctx.read("$.emails[0].email")
将 return null 而不是抛出异常,这要归功于 option SUPPRESS_EXCEPTIONS
.
如果事先不知道路数:
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;
}
option ALWAYS_RETURN_LIST
表示 return 类型是一个列表,即使您有一个或零个结果。
此代码应该非常适合您
//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);
给定 JSON 结构如下:
{
"name":"Some Guy",
"emails":[
{
"description":"primary",
"status":"UNVERIFIED",
"email":"first@first-email.com"
},
{
"description":"home",
"status":"VERIFIED",
"email":"second@second-email.com"
},
{
"description":"away",
"status":"VERIFIED",
"email":"third@third-email.com"
}
]
}
我想要 JSONPath expression 获取状态为 VERIFIED
的 第一个 电子邮件,如果有 none,则只需获取数组中的第一封电子邮件。因此,根据上面的示例,结果将是 second@second-email.com
。给出这个例子:
{
"name":"Some Guy",
"emails":[
{
"description":"primary",
"status":"UNVERIFIED",
"email":"first@first-email.com"
},
{
"description":"home",
"status":"UNVERIFIED",
"email":"second@second-email.com"
}
]
}
结果将是 first@first-email.com
。
JSON路径表达式是否可行?
你实际上有 2 个 JSONPath 表达式,其中第二个(第一封电子邮件)只有在第一个(第一封经过验证的电子邮件)return什么都没有的情况下才应该被评估,所以我认为你无法评估它们同时出现在一个表达式中。
不过,您可以一个接一个地应用它们:
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");
}
如果电子邮件数组为空,ctx.read("$.emails[0].email")
将 return null 而不是抛出异常,这要归功于 option SUPPRESS_EXCEPTIONS
.
如果事先不知道路数:
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;
}
option ALWAYS_RETURN_LIST
表示 return 类型是一个列表,即使您有一个或零个结果。
此代码应该非常适合您
//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);