2017-01-04 1 views
2

Учитывая JSON структурированный, как это:выражения JSONPath, чтобы получить значение из массива, при условии, или только первого значения

{ 
    "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 expression получить первой электронной почты со статусом VERIFIED и если нет, тогда просто получите первое электронное письмо в массиве. Итак, с учетом приведенного выше примера, результатом будет [email protected]. С учетом этого примера:

{ 
    "name":"Some Guy", 
    "emails":[ 
     { 
     "description":"primary", 
     "status":"UNVERIFIED", 
     "email":"[email protected]" 
     }, 
     { 
     "description":"home", 
     "status":"UNVERIFIED", 
     "email":"[email protected]" 
     } 
    ] 
} 

результатом будет [email protected].

Возможно ли это с помощью выражения JSONPath?

+0

Какие реализации JSONPath вы используете? Вам нужно сделать это в одном выражении? – approxiblue

+0

Сегодня я использую реализацию jayway Java, но если у вас есть другие реализации, которые будут работать, я мог бы выяснить, как интегрировать эту реализацию. Я имел в виду делать это в одном выражении «да», но если бы у вас был способ, когда его можно было бы выразить как цепочку выражений, я был бы открыт для рассмотрения этого. Он просто не может требовать, чтобы мой собственный код Java или Javascript обрабатывал промежуточные результаты. – jhericks

ответ

4

У вас фактически есть 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"); 
} 

Если массив электронной почты пуст, ctx.read("$.emails[0].email") возвратит нуль вместо того, чтобы бросать исключение, благодаря optionSUPPRESS_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; 
} 

ALWAYS_RETURN_LISToption означает тип возвращаемого список, даже если у вас есть один или нулевой результат.

+0

Проблема в том, что у меня есть только вход JSON и ключи карты для выражений JSONPath. Я не знаю, что выражения впереди - они настраиваются, поэтому иметь что-то вроде этого метода getEmail не будет работать для меня. – jhericks

+0

@jhericks Метод больше для демонстрации. Вы можете применять эти два выражения один за другим, поэтому вы можете включить оба жестко закодированных выражения в моем примере в аргументы. – approxiblue

+0

Скажем, у меня был массив выражений: '[" $ .emails [? (@. Status == 'VERIFIED')]. Email "," $ .emails [0] .email "]' Какой бы метод выглядел что бы просто повторить эти выражения и дать правильный адрес электронной почты? – jhericks

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); 
+0

Это не учитывает адрес email.status. – jhericks

+0

Это shoul делать. Все параметры первой записи будут сняты. Распечатайте «местоположение» на консоль, чтобы проверить –

+0

. Еще одна проблема заключается в том, что вы не можете принять заказы записей. Массив JSon похож на неупорядоченный список JSon. –