JsonPath-提取满足多个条件的对象? [英] JsonPath - Extract object meeting multiple criteria?

查看:212
本文介绍了JsonPath-提取满足多个条件的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面给出的Json字符串中,我想找到category = m并且"middle"数组包含与该条件匹配的元素的所有元素-元素的"middle"数组具有itemType = Executable的对象.

In the Json string given below, I want to find all elements in which category = m AND the "middle" array contains elements which match this condition - the element's "middle" array has objects whose itemType = Executable.

我想使用jsonpath来获取所需的对象.我宁愿不使用jmespath,因为它对我而言可能太复杂了.但是,我是jsonpath的新手,我无法从过于琐碎或基本的在线教程中找出json查询.我想知道使用编程语言代替获取所需数据是否更好.请告知.

I would like to use jsonpath to get the desired objects. I prefer to not use jmespath because it can be too complex for my purpose. But, I am new to jsonpath and I am not able to figure out the json query from online tutorials which are too trivial or basic. I wonder if its better to use a programming language instead to get the data I need. Please advise.

到目前为止,通过使用此jsonpath查询$.[?(@.category=="m")],我只能提取category = m的元素.我该怎么做剩余部分?

So far, I was able to only extract elements in which category = m by using this jsonpath query $.[?(@.category=="m")]. How do I do the remaining part ?

Json: 概述-每个对象都有一个内容"对象.每个内容对象除其他字段外通常都有一个开始,中间和结束数组.中间数组可以在其中包含多个内容对象,依此类推.一些内容对象只有一个中间数组.我有兴趣在上述内容对象中定位项目.

Json : Overview - Every object has a "content" object. Each content object generally has a start, middle and end array besides other fields. Middle arrays can have multiple content objects inside them and so on. Some of the content objects have only a middle array. I am interested in locating items in such content objects as mentioned above.

请注意,这不是我必须处理的实际json.这种仿制已被SO净化.

Note that this is not the actual json which I have to process. It is an imitation which has been sanitized for SO.

{
  "id": "123",
  "contents": {
    "title": "B1",
    "start": [],
    "middle": [
      {
        "level": "1",
        "contents": {
          "title": "C1",
          "category": "c",
          "start": [],
          "middle": [
            {
              "level": "2",
              "contents": {
                "title": "M1",
                "category": "m",
                "start": [],
                "middle": [
                  {
                    "level": "3",
                    "contents": {
                      "title": "MAT1",
                      "middle": [
                        {
                          "itemType": "Data"
                        }
                      ]
                    }
                  },
                  {
                    "level": "3",
                    "contents": {
                      "title": "MAT2",
                      "middle": [
                        {
                          "itemType": "Executable",
                          "id": "exec1"
                        }
                      ]
                    }
                  },
                  {
                    "level": "3",
                    "contents": {
                      "title": "MAT3",
                      "middle": [
                        {
                          "itemType": "Data"
                        }
                      ]
                    }
                  }
                ],
                "end": []
              }
            },
            {
              "level": "2",
              "contents": {
                "title": "M2",
                "category": "m",
                "start": [],
                "middle": [
                  {
                    "level": "3",
                    "contents": {
                      "title": "MAT1",
                      "middle": [
                        {
                          "itemType": "Data"
                        }
                      ]
                    }
                  },
                  {
                    "level": "3",
                    "contents": {
                      "title": "MAT2",
                      "middle": [
                        {
                          "itemType": "Executable",
                          "id": "exec2"
                        }
                      ]
                    }
                  }
                ],
                "end": []
              }
            }
          ],
          "end": []
        }
      },
      {
        "level": "1",
        "contents": {
          "title": "C2",
          "category": "c",
          "start": [],
          "middle": [
            {
              "level": "2",
              "contents": {
                "title": "M1",
                "category": "m",
                "start": [],
                "middle": [
                  {
                    "level": "3",
                    "contents": {
                      "title": "MAT1",
                      "middle": [
                        {
                          "itemType": "Data"
                        }
                      ]
                    }
                  },
                  {
                    "level": "3",
                    "contents": {
                      "title": "MAT2",
                      "middle": [
                        {
                          "itemType": "Executable",
                          "id": "exec3"
                        }
                      ]
                    }
                  },
                  {
                    "level": "3",
                    "contents": {
                      "title": "MAT3",
                      "middle": [
                        {
                          "itemType": "Data"
                        }
                      ]
                    }
                  }
                ],
                "end": []
              }
            },
            {
              "level": "2",
              "contents": {
                "title": "M2",
                "category": "m",
                "start": [],
                "middle": [
                  {
                    "level": "3",
                    "contents": {
                      "title": "MAT1",
                      "middle": [
                        {
                          "itemType": "Data"
                        }
                      ]
                    }
                  },
                  {
                    "level": "3",
                    "contents": {
                      "title": "MAT2",
                      "middle": [
                        {
                          "itemType": "Executable",
                          "id": "exec4"
                        }
                      ]
                    }
                  },
                  {
                    "level": "3",
                    "contents": {
                      "title": "MAT3",
                      "middle": [
                        {
                          "itemType": "Data"
                        }
                      ]
                    }
                  }
                ],
                "end": []
              }
            }
          ],
          "end": []
        }
      }
    ],
    "end": []
  }
}

推荐答案

上下文

  • 带有嵌套对象的json 1
  • jsonpath表达式语言
  • 在jsonpath和jmespath(或其他JSON表达式引擎)之间进行选择
  • Context

    • json with nested objects1
    • jsonpath expression language
    • choosing between jsonpath and jmespath (or other JSON expression engine)
      • DeveMasterJoe2想从嵌套的JSON中提取一些值
      • 那里有很多jsonpath的实现,它们并不都支持相同的功能
      • 源JSON的结构和规范化将影响使用纯jsonpath完成此操作的难易程度
      • 在选择JSON表达式引擎时,必须权衡多个因素
        • 各种语言的实现之间的一致性如何?
        • 给定语言中有多少种选择?
        • 规范有多清晰?
        • 有多少示例,单元测试或教程可用?
        • 谁在支持它?
        • There are lots of implementations of jsonpath out there, and they do not all support the same features
        • The structure and normalization of the source JSON is going to influence how easily this can be done with pure jsonpath
        • In choosing a JSON expression engine, one has to weigh multiple factors
          • how consistent are the implementations across languages?
          • how many choices are there within a given language?
          • how clear is the specification?
          • how many examples, unit-tests or tutorials are available?
          • who is supporting it?
          • 这是使用python 3.7和jsonpath-ng的示例解决方案
          • 此示例使用jsonpath和python的混合,而不是仅使用纯jsonpath,这是因为JSON嵌套过多
            • 我将其留给其他人提供依赖于纯jsonpath的答案
            • Here is an example solution using python 3.7 and jsonpath-ng
            • This example uses a mix of jsonpath and python instead of just pure jsonpath, because of the heavily-nested JSON
              • I will leave it for someone else to provide an answer that relies on pure jsonpath
              • (例如,为什么没有附加到itemType==Data元素的id字段?)
              • (例如,为什么在所有contents元素上都找不到category?)
              • (例如,如果您明确指定level,为什么可以通过level确定深度时使具有大量嵌套对象的事物复杂化?)
              • (for example, why is there no id field attached to itemType==Data elements?)
              • (for example, why is category not found on all contents elements?)
              • (for example, if you expressly specify level why complicate things with heavily nested objects when you can determine depth by level ?)

              此示例:

              ## import libraries
              import codecs
              import json
              import jsonpath_ng
              from jsonpath_ng.ext import parse
              ##;;
              
              ## init vars
              href="path/to/my/jsonfile/nested_dict.json"
              json_string   = codecs.open(href, 'rb', encoding='utf8').read()
              json_dataroot = json.loads(json_string)
              final_result  = []
              ##;;
              
              ## init jsonpath outer-query
              match         = parse('$..contents.middle[*]').find(json_dataroot)
              ##;;
              
              ## iterate through outer-query and gather subelements
              for ijj,item in enumerate(match):
                ## restrict to desired category == 'm'
                if(match[ijj].value.get('contents',{}).get('category','') == 'm'):
                  ## extract out desired subelements
                  json_datafrag001  = [item.get('contents',{}).get('middle',{})[0] 
                            for item in match[ijj].value.get('contents',{}).get('middle',{})
                            ]
                  match001 = parse("$[?(@.itemType=='Executable')]").find(json_datafrag001)
                  final_result.extend(list(match001[ikk].value for ikk,item in enumerate(match001)))
              pass
              ##;;
              
              ## show final result
              vout = json.dumps(final_result, sort_keys=True,indent=4, separators=(',', ': '))
              print(vout)
              ##;;
              

              ...产生此结果...

              ... produces this result ...

              [
                  {
                      "id": "exec1",
                      "itemType": "Executable"
                  },
                  {
                      "id": "exec2",
                      "itemType": "Executable"
                  },
                  {
                      "id": "exec3",
                      "itemType": "Executable"
                  },
                  {
                      "id": "exec4",
                      "itemType": "Executable"
                  }
              ]
              


              1 (又名字典,关联数组,哈希)


              1 (aka dictionary, associative-array, hash)

              这篇关于JsonPath-提取满足多个条件的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆