Как использовать фильтр Python jsonpath_ng и другие расширенные функции? - PullRequest
0 голосов
/ 11 мая 2018

Я пробую разные способы извлечения полезной информации из JSON с помощью Python. Я пробовал 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
            )
        )
    )
 ]

1 Ответ

0 голосов
/ 16 апреля 2019

Метод find () возвращает список объектов DatumInContext. Таким образом, вы можете использовать разбор списка. Для получения значения из DatumInContext вы можете использовать его значение атрибута, которое будет возвращать то же значение, которое вы получаете в ответ на

jsonpath_rw_ext.match('$.students[?gender=="Female"]', json_obj)

Итак, вместо использования

pprint(female_students)

напрямую. Вы можете использовать female_students , анализируя элемент списка со значением

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