JSONPath表达式,用于在条件或第一个值上从数组中获取值

jhe*_*cks 6 json jsonpath

给定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"
      }
   ]
}
Run Code Online (Sandbox Code Playgroud)

我想要一个JSONPath表达式来获取第一封带有状态的电子邮件,VERIFIED如果没有,那么只需获取数组中的第一封电子邮件.因此,鉴于上面的例子,结果将是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"
      }
   ]
}
Run Code Online (Sandbox Code Playgroud)

结果将是first@first-email.com.

这是否可以使用JSONPath表达式?

app*_*lue 9

你有效地拥有2个JSONPath表达式,其中第二个(第一个电子邮件)只有在第一个(第一个验证的电子邮件)没有返回任何内容时才应该被评估,所以我认为你不能同时评估它们,在一个单独的表达.

您可以一个接一个地应用它们,但是:

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");
}
Run Code Online (Sandbox Code Playgroud)

如果电子邮件数组为空,ctx.read("$.emails[0].email")则返回null而不是抛出异常,这要归功于该选项 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;
}
Run Code Online (Sandbox Code Playgroud)

选项 ALWAYS_RETURN_LIST意味着返回类型是一个列表,即使您有一个或零结果.