【问题标题】:is there a way to sequentialize jsonpath search results in python有没有办法在python中对jsonpath搜索结果进行顺序化
【发布时间】:2021-12-29 17:25:56
【问题描述】:

我有一个嵌套非常多的 json 文件,里面有多个块。 以下是该文件的摘录,它有6层以上的嵌套


{
"title": "main questions",
 "type": "static",
"value":
    {
    "title": "state your name",
    "type": "QUESTION",
    "locator": "namelocator",
    }
}

如果有人能帮我解析一下,我可以在 type = question 时找到标题和定位符(因为文件的不同部分可能会有所不同) 而且也同时发生(考虑到文件的规模,顺序会杀死系统)

我一直在使用下面的代码分别获取title和locator的值 pip install jsonpath(在anaconda终端)

from jsonpath import JSONPath
import json as js
data = js.load(f)# f is the path to .json file
JSONPath('$.[?(@.type== "QUESTION")].locator').parse(data)
JSONPath('$.[?(@.type== "QUESTION")].title').parse(data)

问题是: 我正在获取定位器和标题的列表,但由于无法知道函数解析文件的顺序,所以它们都很混乱 自从我遇到这个问题以来已经有一段时间了,唯一的解决方案是遍历文件以查找所有类型==问题,然后再次循环查找定位器和标题(这对于大量的文件)

【问题讨论】:

  • @rv.kvetch 这是一个虚拟格式,文件实际上只有 json
  • 所以这是一个en.wikipedia.org/wiki/Tree_traversal 的问题?你有没有考虑过用 json.loads(data) 把它解析成一个 python 对象,这样你就可以控制迭代了?
  • @KennyOstrom 不,我没有,我会尽快更新,谢谢 更新:这个对象的格式还是一样的,请问还有其他想法吗?
  • 格式应该是一样的。这个想法是你控制迭代,所以当你找到一个问题时,你把定位器和标题拉在一起。好的,可以包含一个 pip 命令和 import 语句吗?当我在该数据上使用该 expr 时,我只是得到 False。
  • 刚刚包含了 pip 和 import 语句@KennyOstrom

标签: python json jsonpath json-path-expression


【解决方案1】:

关键是解析一次,把找到的对象当作对象,这样就可以把正确的标题和定位符组合在一起。如果需要,它们很容易拆分。

这是一个代码示例,展示了我在 cmets 中做出的所有各种答案。我不知道您使用的是哪个确切的库,但它们似乎都实现了相同的 JSONPath,因此您可能可以使用它。只需更改函数名称和参数顺序以适合您实际拥有的任何库。

from jsonpath import jsonpath
import json

text = """{
"title": "main questions",
"type": "static",
"value":
    {
    "title": "state your name",
    "type": "QUESTION",
    "locator": "namelocator"
    }
}"""

# use jsonpath to find the question nodes
data = json.loads(text)
questions_parsed = jsonpath(obj=data, expr='$.[?(@.type== "QUESTION")]')
print (questions_parsed)

[{'title': 'state your name', 'type': 'QUESTION', 'locator': 'namelocator'}]

# python code to parse the same structure
def find_questions(data):
    if isinstance(data, dict):
        if 'type' in data and 'QUESTION' == data['type']:
            # TODO: write a dataclass, or validate that it has title and locator
            yield data
        elif 'value' in data and isinstance(data['value'], dict):
            value = data['value']
            yield from find_questions(value)
    elif isinstance(data, list):
        for item in data:
            yield from find_questions(item)

questions = [(question['title'], question['locator']) for question in find_questions(json.loads(text))]

就像我说的,如果需要,可以很容易地将一个对象拆分为单独的列表:
How to unzip a list of tuples into individual lists?

titles, locators = (list(t) for t in zip(*questions))
print(titles)
print(locators)

['说出你的名字']
['namelocator']

我使用了这个实现:

pip 显示 jsonpath

名称:jsonpath
版本:0.82
摘要:JSON 的 XPath
主页:http://www.ultimate.com/phil/python/#jsonpath
作者:菲尔·布德尼
作者邮箱:phil@ultimate.com
许可证:麻省理工学院

【讨论】:

  • 非常感谢您花时间解决这个问题。但是,问题不是提取问题和答案,而是通过单个解析找到它们,而不是找到所有类型,然后找到它们对应的问题和答案(通过循环)。我一定会尝试建立一个类来一次性验证定位器和类。再次感谢
  • 你确定这不是一个树遍历问题,就像我在第一条评论中问的那样吗?请再看看那个链接。
  • 我检查了那个链接,它实际上与它无关。
猜你喜欢
  • 2017-04-02
  • 1970-01-01
  • 2013-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-15
  • 1970-01-01
  • 2016-01-09
相关资源
最近更新 更多