在不知道名称的情况下扫描嵌套的json响应以获取特定值

时间:2019-08-09 14:06:55

标签: python json

我从UI收到一个巨大的(超过3000行)JSON响应。我需要浏览整个响应并搜索值“ Not Answered”。找到该值后,我需要获取有关该响应的其他信息。

响应高度嵌套,最多7层。我确实知道该值具有“值”的键,但是该键多次出现在响应中。每个调用的第一个“值”键下的嵌套和项目数可以不同。

这是一小部分响应示例的示例。我将需要查找值“ Not Answered”的每个实例。我没有在值键下的响应中显示其他数据。

{
"data": {
 "reviewData": [
   0: {
     "value": [
       1: {
         "value": "Answer"
       },
       2: {
         "value": "Not Answered"
       },
       3: {
         "value": "Answer"
       }
     ]
   },
   1: {
     "value": [
       1: {
         "value": "Not Answered"
       },
       2: {
         "value": "Not Answered"
       },
       3: {
         "value": "Answer"
        }
      ]
    }
  ]
 }
}

我知道我可以将所有内容放入字符串并使用正则表达式,但这无助于获取所需的其他数据。感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

您可以使用生成器浏览字典并以元组的形式生成导致'Not Answered'值的路径:

def walk(obj):
    for key, value in obj.items():
        if isinstance(value, dict):
            yield from ((key,) + x for x in walk(value))
        elif value == 'Not Answered':
            yield (key,)

对于您的示例,将给出以下输出:

[('data', 'reviewData', '0', 'value', '2', 'value'),
 ('data', 'reviewData', '1', 'value', '1', 'value'),
 ('data', 'reviewData', '1', 'value', '2', 'value')]

如果您需要访问周围的信息,则可以通过对嵌套字典使用reduce __getitem__到任意深度的提供的路径:

from functools import reduce

for path in walk(test_dict):
    info = reduce(lambda obj, key: obj[key], path[:-1], test_dict)

答案 1 :(得分:0)

您可以使用像这样的递归函数:

let pdfView = PDFView() 
let document = PDFDocument(url:urlToOPen)
pdfView.document = document

//then I get the string like this
str =  pdfView.currentSelection?.string ?? ""

//with this workaround I got it working on some PDFs but not all
let dad =   pdfView.currentPage?.dataRepresentation
let text = PDFDocument(data: dad! )
let textfromData = text?.string