Skip to content

Instantly share code, notes, and snippets.

@martinvirtel
Last active November 7, 2017 18:11
Show Gist options
  • Save martinvirtel/366235401cf7fbec503d53eb44109f25 to your computer and use it in GitHub Desktop.
Save martinvirtel/366235401cf7fbec503d53eb44109f25 to your computer and use it in GitHub Desktop.
Ugly JMESPath hack: How to access a parent property
lambdascraper
import jmespath
from jmespath import functions
class CustomFunctions(functions.Functions):
"""
JMESPath hack to retrieve the parent element if you need it.
"""
def __init__(self,context=None):
super().__init__()
self.data={}
@functions.signature({'types': ['string']},{'types': ['string']})
def _func_store(self,s,var):
"""
stores value s in the variable var. can later be retrieved using fetch
"""
self.data[var]=s
return s
@functions.signature({'types': ['string']})
def _func_fetch(self,var):
"""
returns variable var or None
"""
return self.data.get(var,None)
def test() :
import json
input=json.loads("""
{ "name" : "parent name",
"data" : [
{ "x" : 1, "y" : 2 },
{ "x" : 3, "y" : 2 }
]
}
""")
options = jmespath.Options(custom_functions=CustomFunctions())
output = jmespath.search("{ name: store(name,'name'), data: data[][ fetch('name'),x, y] }",input,options=options)
assert output==json.loads("""
{
"name": "parent name",
"data": [
[ "parent name", 1, 2 ],
[ "parent name", 3, 2 ]
]
}
""")
if __name__ == "__main__" :
test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment