Извлечение нескольких объектов JSON на разной глубине с помощью JayWay JSONPath - PullRequest
2 голосов
/ 20 марта 2019

Положение

  • У меня есть JSON
  • Я пытаюсь захватить каждый элемент в массиве, который имеет определенные вложенные объекты. Сложность в том, что некоторые из этих объектов расположены на разной глубине.
  • Я использую JayWay JsonPath https://github.com/json-path/JsonPath,, и мой код работает точно так же, как https://jsonpath.herokuapp.com

Используется на нашей платформе, https://dashdash.com - электронная таблица с интеграциями для известных веб-сервисов (и ваших частных API тоже).

Частный случай (тестируемый)

Рассмотрим следующий исходный JSON , я хочу вернуть только те элементы массива, которые имеют вложенные объекты B, C и G. G находится на другой глубине, чем B и C.

Ниже вы можете увидеть источник и 2 варианта возврата.

источник JSON

[  
   {  
      "A":"val1",
      "B":"val2",
      "C":"val3",
      "D":{  
         "E":[  
            {  
               "F":"val4"
            }
         ],
         "G":[  
            {  
               "H":"val5",
               "I":"val6",
               "J":"val7"
            }
         ]
      }
   },
   {  
      "A":"val8",
      "B":"val9",
      "C":"val10",
      "D":{  
         "E":[  
            {  
               "F":"val11"
            }
         ],
         "G":[  
            {  
               "H":"val12",
               "I":"val13",
               "J":"val14"
            }
         ]
      }
   },
   {  
      "A":"val15",
      "B":"val16"
   },
   {  
      "A":"val8",
      "B":"val9",
      "C":"val10",
      "D":{  
         "E":[  
            {  
               "F":"val11"
            }
         ]
      }
   }
]

Ожидаемый доход Вариант 1.

[
   {
      "B":"val2",
      "C":"val3",
      "G":[
         {
            "H":"val5",
            "I":"val6",
            "J":"val7"
         }
      ]
   },
   {
      "B":"val9",
      "C":"val10",
      "G":[
         {
            "H":"val12",
            "I":"val13",
            "J":"val14"
         }
      ]
   }
]

Ожидаемый доход Вариант 2.

[
   {
      "B":"val2",
      "C":"val3",
      "D":{
         "E":[
            {
               "F":"val4"
            }
         ],
         "G":[
            {
               "H":"val5",
               "I":"val6",
               "J":"val7"
            }
         ]
      }
   },
   {
      "B":"val9",
      "C":"val10",
      "D":{
         "E":[
            {
               "F":"val11"
            }
         ],
         "G":[
            {
               "H":"val12",
               "I":"val13",
               "J":"val14"
            }
         ]
      }
   }
]

Где я

  • Я могу извлечь все элементы массива, которые имеют B, C и D, с помощью запроса $..['B','C','D']

Я пытался извлечь B, C и G, но все следующие запросы не выполняются:

  • $..['B','C','G']: возвращает ноль.
  • $..['B','C',['D'].['G']]: возвращает только объекты внутри G.

Опять же, я использую JayWay JsonPath https://github.com/json-path/JsonPath,, и мой код работает точно так же, как https://jsonpath.herokuapp.com.

Заранее спасибо

Ответы [ 2 ]

3 голосов
/ 02 апреля 2019

Вы можете решить эту проблему, установив конфигурацию JayWay в DEFAULT_PATH_LEAF_TO_NULL (как описано в официальной документации: https://github.com/json-path/JsonPath) и после этого примените нулевую оценку сравнения:

, например:

$.[?(@.A != null && @.B != null && @.D != null &&  @.D.G != null)]

или это:

$.[?((@.A != null && @.B != null) && ((@.D != null &&  @.D.G != null) || (@.G != null)))]

Для установки DEFAULT_PATH_LEAF_TO_NULL вам следует изменить конфигурацию по умолчанию:

Configuration conf = Configuration.defaultConfiguration();
Configuration conf2 = conf.addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL);

Примечание. Если вы используете устаревшую версию jayway, оператор сравненияне может работать правильно, для получения дополнительной информации см. https://code.google.com/archive/p/json-path/issues/27

Я проверил это решение и отлично работал для меня:

Тест выполнен на https://jsonpath.herokuapp.com/ со следующим вводом:

[  
   {  
      "A":"val1",
      "B":"val2",
      "C":"val3",
      "D":{  
         "E":[  
            {  
               "F":"val4"
            }
         ],
         "G":[  
            {  
               "H":"val5",
               "I":"val6",
               "J":"val7"
            }
         ]
      }
   },
   {  
      "A":"val8",
      "B":"val9",
      "C":"val10",
      "D":{  
         "E":[  
            {  
               "F":"val11"
            }
         ],
         "G":[  
            {  
               "H":"val12",
               "I":"val13",
               "J":"val14"
            }
         ]
      }
   },
   {  
      "A":"val15",
      "B":"val16"
   },
   {  
      "A":"val8",
      "B":"val9",
      "C":"val10",
      "D":{  
         "E":[  
            {  
               "F":"val11"
            }
         ]
      }
   }
]

и результат был:

[
   {
      "A" : "val1",
      "B" : "val2",
      "C" : "val3",
      "D" : {
         "E" : [
            {
               "F" : "val4"
            }
         ],
         "G" : [
            {
               "H" : "val5",
               "I" : "val6",
               "J" : "val7"
            }
         ]
      }
   },
   {
      "A" : "val8",
      "B" : "val9",
      "C" : "val10",
      "D" : {
         "E" : [
            {
               "F" : "val11"
            }
         ],
         "G" : [
            {
               "H" : "val12",
               "I" : "val13",
               "J" : "val14"
            }
         ]
      }
   }
]

См. Свидетельство и обратите внимание, что возвращаемое значение NULL установлено в true

Дайте мне знатьесли вам нужна дополнительная помощь по этому вопросу.

2 голосов
/ 02 апреля 2019

Я пробовал несколько разных подходов, и я думаю, что более простое выражение делает свое дело:

$.*[?(@.B && @.C && @.D.G)]

Для этого не требуется никакой специальной конфигурации, кроме по умолчанию (согласно эксперименту, выполненному на https://jsonpath.herokuapp.com и дает следующий результат:

[
   {
      "A" : "val1",
      "B" : "val2",
      "C" : "val3",
      "D" : {
         "E" : [
            {
               "F" : "val4"
            }
         ],
         "G" : [
            {
               "H" : "val5",
               "I" : "val6",
               "J" : "val7"
            }
         ]
      }
   },
   {
      "A" : "val8",
      "B" : "val9",
      "C" : "val10",
      "D" : {
         "E" : [
            {
               "F" : "val11"
            }
         ],
         "G" : [
            {
               "H" : "val12",
               "I" : "val13",
               "J" : "val14"
            }
         ]
      }
   }
]

Что вы думаете?

...