pythonjsonpython-3.xjsonparserjsonpath-ng

How to parse nested information in JSON using jsonpath_ng


I have the following JSON, which came from an API response:

{
    "expand": "names,schema",
    "startAt": 0,
    "maxResults": 50,
    "total": 3,
    "issues": [
        {
            "expand": "",
            "id": "10001",
            "self": "http://www.example.com/10001",
            "key": "ABC-1",
            "fields": [
                {
                    "From":"Ibiza",
                    "To":"Mallorca"
                },                
                {
                    "From":"Mallorca",
                    "To":"Miami"
                }
            ]
        },
        {
            "expand": "",
            "id": "10002",
            "self": "http://www.example.com/10002",
            "key": "ABC-2",
            "fields": [
                {
                    "From":"NYC",
                    "To":"Charlotte"
                },                
                {
                    "From":"Charlotte",
                    "To":"Los Angeles"
                },
                {
                    "From":"Los Angeles",
                    "To":"San Diego"
                }
            ]
        },
        {
            "expand": "",
            "id": "10003",
            "self": "http://www.example.com/10003",
            "key": "ABC-3",
            "fields": [
                {
                    "From":"Denver",
                    "To":"Boson"
                }
            ]
        }
    ]
}

Target

My target would be to print in Python a list of combinations like:

10001 - Ibiza - Mallorca
10001 - Mallorca - Miami
10002 - NYC - Charlotte
10002 - Charlotte - Los Angeles
10002 - Los Angeles - San Diego
10003 - Denver - Boston

What I have done

The following snippet works fine, but I really can't understand how to merge the information. I understand that I should split the whole JSON into smaller parts, one for each item, and then apply the second and third catches...can anybody help me, please?

import jsonpath_ng.ext as jp
import json


data=json.loads(response.text)

# 1st catch: 10001,10002,10003
query = jp.parse("$.issues[*].id")
for match in query.find(data):
    key=match.value
    print(key)

#2nd catch: Ibiza, Mallorca, NYC, ...
query = jp.parse("$.issues[*].fields[*].From")
for match in query.find(data):
    key=match.value
    print(key)

#3nd catch: Mallorca, Miami, Charlotte, ...
query = jp.parse("$.issues[*].fields[*].To")
for match in query.find(data):
    key=match.value
    print(key)

Solution

  • I don't really know that package, but I have used a similar one jmespath. Based on it, I might try:

    results = [
        f"{parent.value['id']} - {child.value['From']} -{child.value['To']}"
        for parent in jp.parse("$.issues[*]").find(data)
        for child in jp.parse("$.fields[*]").find(parent.value)
    ]
    
    for result in results:
        print(result)