Jack Fleeting
Jack Fleeting

Reputation: 24930

Is there a way to get the path to a specific element within the JSON value?

Given this simple example from the jq manual:

[    
    {
        "name":"JSON",
        "good":true        
    },
    {
        "name":"XML",
        "good":false        
    }
]

using this expression:

.[1].name

I get "XML" as output.

And the question: in xpath, for example, there are ways to do the reverse: given an element, an xpath function will return the xpath to the element within the document. Is there a way to do that with jq? That is, given "XML", is there a way to get

.[1].name

as the output?

I am aware of the getpath(PATHS) function, but unless I'm missing something, that's not it.

Upvotes: 3

Views: 1854

Answers (2)

peak
peak

Reputation: 116640

To get the JSON representation of the path(s) of interest, you could write:

paths as $p
| select(getpath($p) == "XML")
| $p

This form is normally the most useful, but it’s easy to transform it into another form if need be, as shown in @OguzIsmail's answer (see also below).

If only the path of the first occurrence is desired, you can simply use first(...), but of course there are different possible conceptions of “first”.

Producing jq-style path expressions

As pointed out by @OguzIsmail, tojson can be used to produce jq-style path expressions (i.e., jq expressions that can be used to fetch a value directly, without getpath), e.g. by adding the following to the above pipeline :

".[" + (map(tojson)|join("][")) + "]"

Upvotes: 2

oguz ismail
oguz ismail

Reputation: 50750

As far as I'm concerned JQ still doesn't have a built-in for that. However, if a path in .[1]["name"] format is also acceptable, that's pretty easy:

  • get paths in array form using path built-in,
  • enclose each path component of type string in double quotes; tojson can be used for that,
  • join all components by ][,
  • and put the result between .[ and ].
path(recurse | select(.=="XML")) | ".[\(map(tojson) | join("]["))]"

Online demo

Upvotes: 3

Related Questions