【问题标题】:get list of json paths in python获取python中的json路径列表
【发布时间】:2021-05-02 00:57:10
【问题描述】:

我正在寻找 json 文件中所有可能的 json 路径的列表 - 可以推荐任何一个吗?

例如:如果输入低于

{
   "_id":{
      "$oid":""
   },
   "aa":false,
   "bb":false,
   "source":"",
   "email":"",
   "createdAt":{
      "$date":""
   },
   "updatedAt":{
      "$date":""
   },
   "cc":"",
   "vv":"",
   "metadata":{
      "vv":"",
      "xx":[{}]
   }
}

o/p:

obj
obj._id
obj._id.$oid
obj.aa
obj.bb
obj.source
obj.email
obj.createdAt
obj.createdAt.$date
obj.updatedAt
obj.updatedAt.$date
obj.cc
obj.vv
obj.metadata
obj.metadata.vv
obj.metadata.xx
obj.metadata.xx[0]

我基本上是在看。这个的python版本:https://www.convertjson.com/json-path-list.htm

我想构建一个通用解决方案,如果有任何 json 文件 - 它将是模式生成的单个值(即换行符分隔的 json 中的一行) 有什么建议吗?

【问题讨论】:

    标签: python json jsonpath json-query


    【解决方案1】:

    您可以使用递归生成器以相当简洁的方式执行此操作。字符串"obj" 有点尴尬,因为它不会出现在数据结构中。另一方面,在末尾添加它很简单:

    def get_paths(d):
        if isinstance(d, dict):
            for key, value in d.items():
                yield f'.{key}'
                yield from (f'.{key}{p}' for p in get_paths(value))
            
        elif isinstance(d, list):
            for i, value in enumerate(d):
                yield f'[{i}]'
                yield from (f'[{i}]{p}' for p in get_paths(value))
    
    paths = ['obj'+s for s in get_paths(d)]
    

    以字符串列表的形式提供路径:

    ['obj._id',
     'obj._id.$oid',
     'obj.aa',
     'obj.bb',
     'obj.source',
     'obj.email',
     'obj.createdAt',
     'obj.createdAt.$date',
     'obj.updatedAt',
     'obj.updatedAt.$date',
     'obj.cc',
     'obj.vv',
     'obj.metadata',
     'obj.metadata.vv',
     'obj.metadata.xx',
     'obj.metadata.xx[0]']
    

    当然,您可以将最后一步包装在一个函数中,并接受一个根对象字符串:

    def get_paths(d, root="obj"):
        def recur(d):
            if isinstance(d, dict):
                for key, value in d.items():
                    yield f'.{key}'
                    yield from (f'.{key}{p}' for p in get_paths(value))
    
            elif isinstance(d, list):
                for i, value in enumerate(d):
                    yield f'[{i}]'
                    yield from (f'[{i}]{p}' for p in get_paths(value))
    
        return (root + p for p in recur(d))
    
    list(get_paths(d))
    # same result
    

    【讨论】:

    • 感谢分享这个 - 我基本上是在寻找基本的 json 过滤器 - 基本上输入将是一个用于过滤的模板 json 并且我需要的输出数据被过滤 - 有什么简单的方法可以做到这一点
    • 我不确定我是否理解@kenzen。过滤器通常有某种谓词来确定什么被过滤,什么不被过滤——不确定它适合这里。如果你能清楚地解释它,它本身可能会成为一个很好的问题。
    • @Mark,我可以请您增强解决方案以提供字典的键路径,其中给定键的值既不是字典也不是列表,所以只获取键的路径值是字符串、整数还是浮点数等?
    【解决方案2】:

    您可以使用以下代码执行此操作:

    mylist = []
    def getKeys(obj, parent="obj"):
      global mylist
      for i in obj.keys():
        mylist.append(parent+"."+i)
        try:
          getKeys(obj[i], parent+"."+i)
        except AttributeError: 
          pass
    getKeys({
       "_id":{
          "$oid":""
       },
       "aa":False,
       "bb":False,
       "source":"",
       "email":"",
       "createdAt":{
          "$date":""
       },
       "updatedAt":{
          "$date":""
       },
       "cc":"",
       "vv":"",
       "metadata":{
          "vv":"",
          "xx":[{}]
       }
    })
    print(mylist)
    

    我将false 更改为False。如果您使用的是 JSON 而不是字典,则可能需要使用 JSON 库将其转换为字典。

    import json
    myDict = json.loads("{"_id":{"$oid":""},"aa":false,"bb":false,"source":"","email":"","createdAt":{"$date":""},"updatedAt":{"$date":""},"cc":"","vv":"","metadata":{"vv":"","xx":[{}]}}")
    

    【讨论】:

    • 这似乎错过了以下列表:obj.metadata.xx[0]
    猜你喜欢
    • 2022-07-11
    • 1970-01-01
    • 1970-01-01
    • 2018-12-19
    • 2016-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多