Jump to content

JSON pointer: Difference between revisions

Line 817:
 
"bad/pointer" => Error pointers must start with a slash or be the empty string
</pre>
 
=={{header|Python}}==
{{trans|JavaScript}}
<syntaxhighlight lang="python">""" rosettacode.org/wiki/JSON_pointer """
 
from functools import reduce
 
 
class JSONPointer:
""" datatracker.ietf.org/doc/html/rfc6901 """
 
def __init__(self, pstring):
""" create a JSON ponter from a string """
self.tokens = parse(pstring)
 
def resolve(self, data):
""" use the pointer on an object """
return reduce(get_item, self.tokens, data)
 
def encode(self):
""" output pointer in string form """
ret = ''
for tok in self.tokens:
ret = ret + '/' + tok.replace('~', '~0').replace('/', '~1')
return ret
 
def to_string(self):
""" output pointer in string form """
return self.encode()
 
 
def parse(pst):
""" tokenize a string for use as JSON pointer """
if pst == '':
return []
if pst[0] != '/':
raise SyntaxError('Non-empty JSON pointers must begin with /')
return [a.replace('~1', '/').replace('~0', '~') for a in pst.split('/')][1:]
 
 
def get_item(obj, token):
"""
NOTE:
- string primitives 'have own' indices and `length`.
- Arrays have a `length` property.
- A property might exist with the value `undefined`.
- obj[1] is equivalent to obj['1'].
"""
if isinstance(obj, list) and isinstance(token, str):
return obj[int(token)]
return obj[token]
 
 
if __name__ == '__main__':
 
DOC = {
'wiki': {
'links': [
'https://rosettacode.org/wiki/Rosetta_Code',
'https://discord.com/channels/1011262808001880065',
],
},
'': 'Rosetta',
' ': 'Code',
'g/h': 'chrestomathy',
'i~j': 'site',
'abc': ['is', 'a'],
'def': {'': 'programming'},
}
 
EXAMPLES = [
'',
'/',
'/ ',
'/abc',
'/def/',
'/g~1h',
'/i~0j',
'/wiki/links/0',
'/wiki/links/1',
'/wiki/links/2',
'/wiki/name',
'/no/such/thing',
'bad/pointer',
]
 
for exa in EXAMPLES:
try:
pointer = JSONPointer(exa)
result = pointer.resolve(DOC)
print(f'"{exa}" -> "{result}"')
except (SyntaxError, IndexError, KeyError) as error:
print(f'Error: {exa} does not exist: {error}')
</syntaxhighlight>{{out}}
<pre>
"" -> "{'wiki': {'links': ['https://rosettacode.org/wiki/Rosetta_Code', 'https://discord.com/channels/1011262808001880065']}, '': 'Rosetta', ' ': 'Code', 'g/h': 'chrestomathy', 'i~j': 'site', 'abc': ['is', 'a'], 'def': {'': 'programming'}}"
"/" -> "Rosetta"
"/ " -> "Code"
"/abc" -> "['is', 'a']"
"/def/" -> "programming"
"/g~1h" -> "chrestomathy"
"/i~0j" -> "site"
"/wiki/links/0" -> "https://rosettacode.org/wiki/Rosetta_Code"
"/wiki/links/1" -> "https://discord.com/channels/1011262808001880065"
Error: /wiki/links/2 does not exist: list index out of range
Error: /wiki/name does not exist: 'name'
Error: /no/such/thing does not exist: 'no'
Error: bad/pointer does not exist: Non-empty JSON pointers must begin with /
</pre>
 
4,108

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.