【问题标题】:How to use Python jsonpath_ng filter and other extended features?如何使用 Python jsonpath_ng 过滤器和其他扩展功能?
【发布时间】:2018-05-11 07:18:26
【问题描述】:

我正在尝试使用 Python 从 JSON 中提取有用信息的不同方法。我尝试了 jsonpath_rw_ext 和 jsonpath_ng。现在我可以使用 jsonpath_rw_ext 但 jsonpath_ng 不起作用。我不想放弃 jsonpath_ng 因为我可能没有以正确的方式使用它。检查以下代码:

import jsonpath_rw_ext
from jsonpath_ng.ext import parse
import json
from pprint import pprint


json_str = '''{
    "students": [
        {"name": "Peter", "gender": "Male", "age": 20},
        {"name": "Mary", "gender": "Female", "age": 30},
        {"name": "Susan", "gender": "Female", "age": 40}
    ],
    "teachers": [
        {"name": "William", "gender": "Male", "age": 30},
        {"name": "John", "gender": "Male", "age": 40},
        {"name": "Lucy", "gender": "Female", "age": 50}
    ]
}'''

json_obj = json.loads(json_str)
print 'jsonpath_rw_ext:'
female_students = jsonpath_rw_ext.match('$.students[?gender=="Female"]', json_obj)
pprint(female_students)
print 'jsonpath_ng:'
female_students = parse('$.students[?gender=="Female"]').find(json_obj)
pprint(female_students)

jsonpath_rw_ext部分输出如下结果,正常: jsonpath_rw_ext:

[{u'age': 30, u'gender': u'Female', u'name': u'Mary'},
 {u'age': 40, u'gender': u'Female', u'name': u'Susan'}]

但是 jsonpath_ng 部分输出以下结果,我无法理解。 jsonpath_ng 返回以下结果是否有任何特定原因?我怎样才能以简单的方式得到类似的结果?

jsonpath_ng 返回的结果:

[
    DatumInContext(
        value={
            u'gender': u'Female', u'age': 30, u'name': u'Mary'
        }, 
        path=<jsonpath_ng.jsonpath.Index object at 0x000000000315AA90>, 
        context=DatumInContext(
            value=[
                {u'gender': u'Male', u'age': 20, u'name': u'Peter'}, 
                {u'gender': u'Female', u'age': 30, u'name': u'Mary'}, 
                {u'gender': u'Female', u'age': 40, u'name': u'Susan'}
            ], 
            path=Fields('students'), 
        context=DatumInContext(
            value={
                u'students': [
                    {u'gender': u'Male', u'age': 20, u'name': u'Peter'}, 
                    {u'gender': u'Female', u'age': 30, u'name': u'Mary'}, 
                    {u'gender': u'Female', u'age': 40, u'name': u'Susan'}
                ], 
                u'teachers': [
                    {u'gender': u'Male', u'age': 30, u'name': u'William'}, 
                    {u'gender': u'Male', u'age': 40, u'name': u'John'}, 
                    {u'gender': u'Female', u'age': 50, u'name': u'Lucy'}
                ]
            }, 
            path=Root(), 
            context=None
        )
        )
    ),
    DatumInContext(
        value={u'gender': u'Female', u'age': 40, u'name': u'Susan'}, 
        path=<jsonpath_ng.jsonpath.Index object at 0x000000000315ABA8>, 
        context=DatumInContext(
            value=[
                {u'gender': u'Male', u'age': 20, u'name': u'Peter'}, 
                {u'gender': u'Female', u'age': 30, u'name': u'Mary'}, 
                {u'gender': u'Female', u'age': 40, u'name': u'Susan'}
            ], 
            path=Fields('students'), 
            context=DatumInContext(
                value={
                    u'students': [
                        {u'gender': u'Male', u'age': 20, u'name': u'Peter'}, 
                        {u'gender': u'Female', u'age': 30, u'name': u'Mary'}, 
                        {u'gender': u'Female', u'age': 40, u'name': u'Susan'}
                    ], 
                    u'teachers': [
                        {u'gender': u'Male', u'age': 30, u'name': u'William'}, 
                        {u'gender': u'Male', u'age': 40, u'name': u'John'}, 
                        {u'gender': u'Female', u'age': 50, u'name': u'Lucy'}
                    ]
                }, 
                path=Root(), 
                context=None
            )
        )
    )
 ]

【问题讨论】:

    标签: json jsonpath


    【解决方案1】:

    find() 方法返回 DatumInContext 对象的列表。所以你可以使用 List 解析。 要从 DatumInContext 获取值,您可以使用其属性值,该值将返回与您响应

    时获得的值相同的值
    jsonpath_rw_ext.match('$.students[?gender=="Female"]', json_obj)
    

    所以,不要使用

    pprint(female_students)
    

    直接,你可以通过解析列表项的值来使用female_students

    pprint([match.value for match in female_students])
    

    【讨论】:

    • 完成答案:是的,find() 函数返回一个列表是有原因的(检查:type(female_students))。该列表为您提供了两个返回答案的上下文 - 您可以遍历它到父对象。答案的直接父对象是students 数组(path=Fields('students')),父对象的父对象是root 对象(path=Root()),root 没有父对象(context=None)。
    【解决方案2】:

    对于使用 jsonpath_ng 的单行解决方案,请使用:

    [match.value for match in parse('$.students[?gender=="Female"]').find(json_obj)]
    

    这会正确返回:

    [{'name': 'Mary', 'gender': 'Female', 'age': 30},
     {'name': 'Susan', 'gender': 'Female', 'age': 40}]
    

    【讨论】:

      猜你喜欢
      • 2017-01-06
      • 1970-01-01
      • 1970-01-01
      • 2016-01-17
      • 2019-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多