‘jsondata.jsonpointer’ - Module

Provides classes for the JSONPointer definition in accordance to RFC6901 and relative pointers draft-1/2018.

Constants

JSON Notation

Notation of the API - in/out, see jsodnata.__init__ .

Node Types

Valid node types represented by Python types.

VALID_NODE_TYPE = (
    dict,
    list,
    str,
    unicode,  # Python2, mapped in Python3 to str
    int,
    float,
    bool,
    None, )

Character Set

For Python3 these are identical to UTF-8.

  • CHARSET_UTF(0) Unicode.
  • CHARSET_STR(1) - Python string.

JSONPointer

Represents exactly one JSONPointer in compliance with IETF and ECMA standards [RFC6901], [RELPOINTER], and [ECMA404]. The JSONPointer is provided at the API as a utf(-8) string, while the processed represenation is a list vector.

  • self.raw:

    Raw input of the pointer string for the logical API.

  • self:

    Split elements of the pointer path as a list of keys and idexes.

The class JSONPointer is derived from the list class and manages the path elements as items:

ptrlist := (<EMPTY>|plist)

<EMPTY> := "empty list, represents the whole document relative to it's root"

plist := pkey [, plist ]

pkey := (''|int|keyname)

'' := "the empty string is a valid key [RFC6901]_ and [RELPOINTER]_"
int := "integer index of an array item, just digits"
keyname := "the valid name of an object/property entry"

The empty quotation within a string has context specific semantics.

  • pointer == ‘’ == ‘”“’

    The whole document.

  • pointer == ‘/”“’ == ‘/’

    The top object node with an empty string as a key.

  • pointer == ‘/any/path/”“/and/more’

    Any node path entry with an empty string as a key.

The JSONPointer:

"/address/0/streetName"

is represented as:

['address', 0, 'streetName' ]

The following special cases are handled:

""      <=> []                 # the whole document
"/"     <=> ['']               # the top of current document, or sub-document
"///"   <=> ['', '', '']       # a pointer path with empty keys
"#"     <=> []                 # the whole document defined as URI fragment
"#/"    <=> []                 # the top of current document referenced by a URI fragment
"#///"  <=> ['', '', '']       # a fragment pointer path with empty keys

The relative pointer adds the syntax:

"0<rfc6901-path>"              # document node relative to offset anchor
"[1-9][0-9]*<rfc6901-path>"    # document node relative to offset anchor

"0#"                           # the actual document node key/index of the offset anchor
"[1-9][0-9]#"                  # the key/index at the resulting document node

The implemented interpretation of the following cases is similar to the common handling of filesystem functions when a directory above the root directory is selected. E.g. in case of Linux with

[acue@somewhere dirXY]$ cd /
[acue@somewhere /]$ pwd
/
[acue@somewhere /]$ cd ../../../../
[acue@somewhere /]$ pwd
/
[acue@somewhere /]$

Due to the lack of definition within the current standards, the similar behavior is defined for the jsondata package. The offset-pointer defines the starting position within the JSON document [RELPOINTER]:

rel-pointer = "0", offset-pointer=""      =>  ""  # the whole document
rel-pointer = "4", offset-pointer=""      =>  ""  # still the whole document
rel-pointer = "4", offset-pointer="/a/b"  =>  ""  # again the whole document

The JSON pointer is by definition in any case actually a relative pointer.

  • rfc6901 - relative to the top of the document
  • relative pointer - relative to an offset pointer within the document

The introduction of a relative pointer [RELPOINTER] keeps and reuses the previous definitions and adds some syntax extensions:

  • Notation for the reference of upper nodes within the hierarchy of the current JSON document.
  • Addition of an offset pointer within the current JSON document as the anchor for the relative pointer.
  • A notation for the get-request of the key or index of the containing element of the resulting node pointed to.

The methods and operators of JSONPointer implement the previous standards for the pointer. These handle by definition the pointer data itself, which is used to address the data within a specific JSON document. The methods of this class support in most cases multiple input formats of the JSONPointer.

‘str’:
A string in accordance to RFC6901 or relative pointer/Draft-1/2018.
‘int’:
A numeric value in case of an array index.
‘JSONPointer’:
Another instance of the class.
‘list’:
Expects a path list containing the elements of a JSON pointer.

The JSONPointer class by itself is focused on the path pointer itself, though the provided operations do not alter the content of the refrenced JSON document. The pointer provides the hook into the JSON document.

class jsondata.jsonpointer.JSONPointer(ptr, **kargs)[source]

Represents exactly one JSONPointer in compliance with IETF RFC6901 and relative-pointer/draft-1/2018

Attributes

  • JSONPointer.isfragment

    True for a URI fragment [RFC6901]. Valid if isrel is False.

    This attribute is read-only.

  • JSONPointer.isrel

    • True for a relative pointer [RELPOINTER]
    • False for a standard JSON pointer or a JSON URI fragment [RFC6901].

    This attribute is read-only.

  • JSONPointer.isrelpathrequest

    Valid only if isrel is True, defines the type of a relative pointer.

    • True when a relative pointer, e.g.

      "3/a/b/c"
      "3"
      
    • False for a key or index get-request, e.g.

      "3#"
      

    This attribute is read-only.

  • JSONPointer.raw

    Raw input string for JSONPointer for internal use.

  • JSONPointer.start

    The resulting start offset after processing of JSONPointer.startrel and the integer index of the relative JSONPointer.

    This is pre-processed in any case for each modification of the startrel attribute, independent of the value provided by the attribute strict.

    This attribute is read-only.

  • JSONPointer.startrel

    The raw pointer offset to the sub node within the JSON document as the start node for the application of the relative pointer. Referenced as the “starting” node in [RELPOINTER].

    This attribute is read-only.

  • JSONPointer.strict

    Controls two charcteristics of the behaviour of relative pointers:

    • Example document from [RELPOINTER]:

      jsondata =    {
         "foo": ["bar", "baz"],
         "highly": {
            "nested": {
               "objects": true
            }
         }
      }
      
    • integer prefix overflow

      The integer prefix of a relative pointer may lead to a starting point exceeding the top of the document. For example

      startrel   = ""
      relpointer = "4/"
      

      The result is:

      strict=True:  raises an exception
      strict=False: results in the whole document
      
    • JSONPointer.startrel

      Controls the behavior of the JSONPointer.startrel offset. This is due to the circumstance, that the application of the integer prefix on a non-existent node could result in a valid node. When strict is True teh existens mandatory and is checked before the application of the integer prefix, when False the integer prefix is applied without verification of the startrel.

      The following relative pointers

      startrel    = "/foo/2"
      relpointer0 = "2/highly/nested/objects"
      relpointer1 = "4/highly/nested/objects"
      

      result in

      strict=True:  raises an exception
      strict=False: true
      

      The case strict=False covers here two variants,

      • relpointer0

        The relative start position defined by the integer index ‘2’ is valid, while the startrel position is not.

      • relpointer1

        The relative start position defined by the integer index ‘4’ lead to an document overflow and is handled as defined by the previous rule. Thus the non-valid startrel position leads to a valid node when the integer prefix is applied, the whole document.

    This attribute is read-only.

Functions

fetch_pointerpath

jsondata.jsonpointer.fetch_pointerpath(node, base, restype=1)[source]

Converts the address of node within the data structure base into a corresponding pointer path. The current implementation is search based, thus may cause performance issues when frequently applied, or processing very large structures.

For example:

nodex = {'a': 'pattern'}
data = {0: nodex, 1: [{'x':[nodex}]]}

res = fetch_pointerpath(nodex, data)

res = [
   [0],
   [1, 0, 'x', 0]
]

Args:

node:
Address of Node to be searched for.
base:
A tree top node to search the subtree for node.
restype:

Type of search.

M_FIRST: The first match only.
M_LAST: The first match only.
M_ALL: All matches.

Returns:

Returns a list of lists, where the contained lists are pointer pathlists for matched elements.

  • restype:=M_FIRST: ‘[[<first-match>]]’,
  • restype:=M_LAST: ‘[[<last-match>]]’,
  • restype:=M_ALL: ‘[[<first-match>],[<second-match>],...]’

Raises:

JSONDataError

Methods

__init__

JSONPointer.__init__(ptr, **kargs)[source]

Normalizes and stores a JSONPointer. The internal representation depends on the type.

  • absolute path:

    A list of ordered items representing the path items.

  • relative path:

    Relative paths in addition provide a positive numeric offset of outer containers [RELPOINTER].

Processes the ABNF of a JSON Pointer from RFC6901 and/or a relative JSON Pointer(draft 2018).

Attributes:

For details see manuals.

  • isfragment
  • isrel
  • raw
  • start
  • startrel
Args:
ptr:

A JSONPointer to be represented by this object. The supported formats are:

ptr := (
    JSONPointer                  # [RFC6901] or [RELPOINTER]
    | <rfc6901-string>           # [RFC6901]
    | <relative-pointer-string>  # [RELPOINTER]
    | <pointer-items-list>       # non-URI-fragment pointer path items of [RFC6901]
    )
JSONPointer:
A valid object, is copied into this object, see ‘deep’. Supports rfc6901 [RFC6901] and relative pointers [RELPOINTER].
rfc6901-string:
A string i accordance to RFC6901 [RFC6901].
relative-pointer-string:
Draft standard, currently experimental [RELPOINTER].
pointer-items-list:
Expects a path list, where each item is processed for escape and unquote. Supports rfc6901 pointers [RFC6901].

Containing:

  • absolute JSON Pointer
  • relative JSON Pointer, requires the keyword argument startrel

kargs:

debug:
Enable debugging.
deep:
Applies for copy operations on structured data ‘deep’ when ‘True’, else ‘shallow’ only. Flat data types are copied by value in any case.
node:
Force to set the pointed node in the internal cache.
replace:

Replace masked characters, is applied onto the ptr parameter only. For the replacement of startrel create and pass an object JSONPointer.

replace := (
     True    # replaces rfc6901 escape sequences: ~0 and ~1
   | False   # omit unescaping
)

Note

Match operations on address strings are proceeded literally, thus the escaped characters should be consistent, see rfc6901, Section 3.

default := False

startrel:

Start node for relative JSON Pointers. Is evaluated only in combination with a relative path, else ignored.

startrel := (
     JSONPointer           # supports [RFC6901]_ and [RELPOINTER]_
   | <rfc6901-string>      # supports [RFC6901]_
   | <rel-pointer-string>  # supports only relative to whole-document '0/...'
)

default := “” # whole document

Returns:
When successful returns True, else returns either False, or raises an exception. Success is the complete addition only, thus one failure returns False.
Raises:
JSONPointerError:

__repr__

JSONPointer.__repr__()[source]

Returns the attribute self.__raw, which is the raw input JSONPointer.

Args:
None
Attributes:
Evaluates self.__isrel
Returns:
For relative paths: ::

(<start-offset>, <pointer>)

start-offset := [<self.startrel>] pointer := [<self>]

For RFC6901 paths:

<pointer>

pointer := [<self>]
Raises:
pass-through

__str__

JSONPointer.__str__()[source]

Returns the string for the processed path.

Args:
None
Attributes:
Evaluates self.__isrel
Returns:
For relative paths: ::

(<start-offset>, <pointer>)

start-offset := [<self.startrel>] pointer := [<self>]

For RFC6901 paths:

<pointer>

pointer := [<self>]
Raises:
pass-through

check_node_or_value

JSONPointer.check_node_or_value(jsondata, parent=False)[source]

Checks the existence of the corresponding node within the JSON document.

Args:
jsondata:
A valid JSON data node.
parent:
If True returns the parent node of the pointed value.
Returns:
True or False
Raises:

JSONPointerError:

pass-through

copy_path_list

JSONPointer.copy_path_list(parent=False)[source]

Returns a deep copy of the objects pointer path list.

Args:
parent:
The parent node of the pointer path.
Returns:
A copy of the path list.
Raises:
none

evaluate

JSONPointer.evaluate(jsondata, parent=False)[source]

Gets the value resulting from the current pointer.

Args:
jsondata:

A JSON data node.

jsondata := (
    JSONData
    | list
    | dict
    )
parent:
Return the parent node of the pointed value. When parent is selected, the pointed child node is not verified.
Returns:
The referenced value.
Raises:

JSONPointerError:

pass-through

get_node_and_child

JSONPointer.get_node_and_child(jsondata)[source]

Returns a tuple containing the parent node and self as the child.

Args:
jsondata:
A valid JSON data node.
Returns:

The the tuple:

(p, c):
   p: Node reference to parent container.
   c: Node reference to self as the child.
Raises:

JSONPointerError:

pass=through

get_node_and_key

JSONPointer.get_node_and_key(jsondata)[source]

Returns a tuple containing the parent node and the key of current.

Args:
jsondata:
A valid JSON data node.
Returns:

The the tuple:

(n, k):
   n: Node reference to parent container.
   k: Key for self as the child entry:

      k := (
           <list-index>
         | <dict-key>
         | None
      )

      list-index: 'int'
      dict-key: 'UTF-8'
      None: "for root-node"
Raises:

JSONPointerError:

pass-through

get_node_exist

JSONPointer.get_node_exist(jsondata, parent=False)[source]

Returns two parts, the exisitng node for valid part of the pointer, and the remaining part of the pointer for the non-existing sub-path.

This method works similar to the ‘evaluate’ method, whereas it handles partial valid path pointers, which may also include a ‘-‘ in accordance to RFC6902.

Therefore the non-ambiguous part of the pointer is resolved, and returned with the remaining part for a newly create. Thus this method is in particular foreseen to support the creation of new sub data structures.

The ‘evaluate’ method therefore returns a list of two elements, the first is the node reference, the second the list of the remaining path pointer components. The latter may be empty in case of a fully valid pointer.

Args:
jsondata:
A valid JSON data node.
parent:
Return the parent node of the pointed value.
Returns:
The node reference, and the remaining part. ret:=(node, [<remaining-path-components-list>])
Raises:
JSONPointerError: forwarded from json

get_node_value

JSONPointer.get_node_value(jsondata, cp=2, **kargs)[source]

Gets the copy of the corresponding node. Relies on the standard package ‘json’.

Args:
jsondata:
A valid JSON data node.
cp:

Type of returned copy.

cp := (
     C_DEEP
   | C_REF
   | C_SHALLOW
)
kargs:
valtype:
Type of requested value.
Returns:
The copy of the node, see option copy.
Raises:

JSONPointerError

pass-through

get_path_list

JSONPointer.get_path_list()[source]

Gets for the corresponding path list of the object pointer for in-memory access on the data of the ‘json’ package.

Args:
none
Returns:
The path list.
Raises:
none

get_path_list_and_key

JSONPointer.get_path_list_and_key()[source]

Gets for the corresponding path list of the object pointer for in-memory access on the data of the ‘json’ package.

Args:
none
Returns:
The path list.
Raises:
none

get_pointer

JSONPointer.get_pointer(jsondata=None, **kargs)[source]

Gets the object pointer in compliance to RFC6901 or relative pointer/draft-01/2018.

The result is by default the assigned pointer itself without verification. Similar in case of a relative pointer the start offset is ignored by default and no verification is performed.

The following options modify this behaviour:

  • superpose - superposes the startrel offset with the pointer
  • verify - verifies the actual existence of the nodes and/or intermediate nodes

The options could be applied combined.

Args:
kargs:
returntype:

Defines the return type.

returntype := (
     RT_DEFAULT     | 'default'
   | RT_LST         | 'list'      | list
   | RT_JSONPOINTER | 'jpointer'
)
superpose:

Is only relevant for relative paths. Superposes the offset startrel with the pointer into the resulting final pointer. By default nodes are not verified, see verify parameter.

default := True

verify:

Verifies the “road” of the superposed pointers.

verify := (
     V_DEFAULT | 'default'
   | V_NONE    | 'none'    | None    # no checks at all
   | V_FINAL   | 'final'             # checks final result only
   | V_STEPS   | 'steps'             # checks each intermediate directory
)

default := None

Returns:
The new pointer in a choosen format, see returntype.
Raises:
none

get_pointer_and_key

JSONPointer.get_pointer_and_key(jsondata=None, **kargs)[source]

Get the resulting pointer and key from the processing of the pointer and the optional starting node stratrel.

get_pointer_str

JSONPointer.get_pointer_str(jsondata=None, **kargs)[source]

Gets the objects pointer string in compliance to RFC6901 or relative pointer/draft-01/2018.

The result is by default the assigned pointer itself without verification. Similar in case of a relative pointer the start offset is ignored by default and no verification is performed.

The following options modify this behaviour:

  • superpose - superposes the startrel offset with the pointer
  • verify - verifies the actual existence of the nodes and/or intermediate nodes

The options could be applied combined.

Args:
kargs:
forcenotation:

Force the output notation for string representation to:

forcenotation := (
     NOTATION_NATIVE           # original format with unescape
   | NOTATION_JSON             # transform to resulting pointer
   | NOTATION_HTTP_FRAGMENT    # return a fragment with encoding
   | NOTATION_JSON_REL         # resulting relative pointer
   | NOTATION_RAW              # raw input
)

default := NOTATION_NATIVE

REMINDER: Applicable for return type string only.

superpose:
Is only relevant for relative paths. Superposes the offset startrel with the pointer into the resulting final pointer. By default nodes are not verified, see verify parameter.
Returns:
The new pointer in a choosen format, see returntype.
Raises:
none

get_raw

JSONPointer.get_raw()[source]

Gets the objects raw 6901-pointer.

Args:
none
Returns:
The raw path.
Raises:
none

get_relupidx

JSONPointer.get_relupidx()[source]

Returns the resulting integer prefix.

get_start

JSONPointer.get_start()[source]

Returns the resulting start pointer after the application of the integer prefix.

get_startrel

JSONPointer.get_startrel()[source]

Returns the raw start pointer.

isfragment

JSONPointer.isfragment()[source]

Checks whether a http fragment.

isrelpathrequest

JSONPointer.isrelpathrequest()[source]

Checks whether a path request.

isrel

JSONPointer.isrel()[source]

Checks whether a relative pointer.

isvalid_nodetype

JSONPointer.isvalid_nodetype(x)[source]

Checks valid node types of in-memory JSON data.

isvalrequest

JSONPointer.isvalrequest()[source]

Checks whether a value request.

Operators

The syntax displayed for provided operators is:

S: self
x: parameter
n: numerical parameter for shift operators.

Thus the position of the opreator and parameteres is defined as follows:

z = S + x: LHS: __add__
z = x + S: RHS: __radd__
S += x:    LHS: __iadd__

‘S+x’

JSONPointer.__add__(x)[source]

Appends a Pointer to self.

Args:
x:

A valid JSONPointer of type:

x := (
   JSONPointer - fragment
   | JSONPointer - relative-pointer
   | relative pointer
   )
Returns:
A new object of JSONPointer
Raises:
JSONPointerError:

‘S(x)’

JSONPointer.__call__(x, *args, **kargs)[source]

Evaluates the pointer value on the document.

Args:
x:
A valid JSON document.
Returns:
The resulting pointer value.
Raises:
JSONPointerError

‘S==x’

JSONPointer.__eq__(x)[source]

Compares this pointer with x.

Args:
x:
A JSONPointer object.
Returns:
True or False
Raises:
JSONPointerError

‘S>=x’

JSONPointer.__ge__(x)[source]

Checks containment(>=) of another pointer within this.

The weight of contained entries is the criteria, though the shorter is the bigger. This is true only in case of a containment relation.

The number of equal path pointer items is compared.

Args:
x:
A valid Pointer.
Returns:
True or False
Raises:
JSONPointerError:

‘S>x’

JSONPointer.__gt__(x)[source]

Checks containment(>) of another pointer or object within this.

The number of equal items is compared.

Args:
x:
A valid Pointer.
Returns:
True or False
Raises:
JSONPointerError:

‘S+=x’

JSONPointer.__iadd__(x)[source]

Add in place x to self, appends a path.

Args:
x:
A valid Pointer.
Returns:
‘self’ with updated pointer attributes
Raises:
JSONPointerError:

‘S<x’

JSONPointer.__le__(x)[source]

Checks containment(<=) of this pointer within another.

The number of equal items is compared.

Args:
x:
A valid Pointer.
Returns:
True or False
Raises:
JSONPointerError:

‘S<x’

JSONPointer.__lt__(x)[source]

Checks containment(<) of this pointer within another.

The number of equal items is compared.

Args:
x:
A valid Pointer.
Returns:
True or False
Raises:
JSONPointerError:

‘S!=x’

JSONPointer.__ne__(x)[source]

Compares this pointer with x.

Args:
x:
A valid Pointer.
Returns:
True or False
Raises:
JSONPointerError

‘x+S’

JSONPointer.__radd__(x)[source]

Adds itself as the right-side-argument to the left.

This method appends ‘self’ to a path fragment on the left. Therefore it adds the path separator on it’s left side only. The left side path fragment has to maintain to be in accordance to RFC6901 by itself.

Once ‘self’ is added to the left side, it terminates it’s life cycle. Thus another simultaneous add operation is handled by the resulting other element.

Args:
x:
A valid Pointer.
Returns:
The updated input of type ‘x’ as ‘x+S(x)’
Raises:
JSONPointerError:

Iterators

iter_path

JSONPointer.iter_path(jsondata=None, **kargs)[source]

Iterator for the elements of the path pointer itself.

Args:
jsondata:
If provided a valid JSON data node, the path components are successively verified on the provided document.
kargs:
parent:
Uses the path pointer to parent node.
rev:
Reverse the order, start with last.
superpose:

Is only relevant for relative paths, for rfc6901 defined paths the parameter is ignored. When True superposes the offset startrel with the pointer into the resulting final pointer. By default nodes are not verified, see verify parameter.

superpose := (
     True   # iterates resulting paths from *startrel*
   | False  # iterates the path only
)

default := True

Returns:
Yields the iterator for the current path pointer components.
Raises:
JSONPointerError: forwarded from json

iter_path_nodes

JSONPointer.iter_path_nodes(jsondata, parent=False, rev=False)[source]

Iterator for the elements the path pointer points to.

Args:
jsondata:
A valid JSON data node.
parent:
Uses the path pointer to parent node.
rev:
Reverse the order, start with last.
Returns:
Yields the iterator of the current node reference.
Raises:
JSONPointerError: forwarded from json

iter_path_subpathdata

JSONPointer.iter_path_subpathdata(jsondata=None, parent=False, rev=False)[source]

Successive iterator for the resulting sub-paths and the corresponding nodes.

Args:
jsondata:
If provided a valid JSON data node, the path components are successively verified on the provided document.
parent:
Uses the path pointer to parent node.
rev:
Reverse the order, start with last.
Returns:

Yields the iterator for the tuple of the current slice of the path pointer and the reference of the corresponding node.

(<path-item>, <sub-path>, <node>)

path-item: copy of the item
sub-path:  copy of the current subpath
node:      reference to the corresponding node
Raises:
JSONPointerError: forwarded from json

iter_path_subpaths

JSONPointer.iter_path_subpaths(jsondata=None, parent=False, rev=False)[source]

Successive iterator for the resulting sub-paths the path pointer itself.

Args:
jsondata:
If provided a valid JSON data node, the path components are successively verified on the provided document.
parent:
Uses the path pointer to parent node.
rev:
Reverse the order, start with last.
Returns:
Yields the iterator for the copy of the current slice of the path pointer.
Raises:
JSONPointerError: forwarded from json

Exceptions

exception jsondata.JSONPointerError(*arg)[source]

Pointer error.

exception jsondata.JSONPointerTypeError(*arg)[source]

Pointer type error, the JSON pointer syntax does not represent a valid pointer.