使用JayWay JSONPath提取不同深度的多个JSON对象

问题描述 投票:2回答:2

Situation

这是在我们的平台上使用https://dashdash.com - 一个电子表格,集成了已知的Web服务(以及您的私有API)。

Particular case (testable)

考虑以下源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"
            }
         ]
      }
   }
]

Where I am

  • 我可以使用查询$..['B','C','D']提取所有具有B,C和D的数组元素

我试图提取B,C和G,但以下所有查询都失败了:

  • $..['B','C','G']:返回null。
  • $..['B','C',['D'].['G']]:仅返回G内的对象。

我再次使用JayWay JsonPath https://github.com/json-path/JsonPath,我的代码就像https://jsonpath.herokuapp.com一样。

提前致谢

java jsonpath
2个回答
2
投票

我一直在尝试一些不同的方法,我认为一个更简单的表达式可以解决这个问题:

$.*[?(@.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"
            }
         ]
      }
   }
]

你怎么看?


3
投票

您可以解决此问题,将JayWay设置为DEFAULT_PATH_LEAF_TO_NULL配置(如官方文档中所述:https://github.com/json-path/JsonPath),然后应用null比较评估:

像这样:

$.[?(@.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"
            }
         ]
      }
   }
]

See the evidence and note that returning null option is set to true

如果您需要任何进一步的帮助,请与我们联系。

© www.soinside.com 2019 - 2024. All rights reserved.