Package jsondata :: Module JSONData :: Class JSONData
[hide private]
[frames] | no frames]

Class JSONData

source code


Representation of a JSON based object data tree.

This class provides for the handling of the in-memory data
by the main hooks 'data', and 'schema'. This includes generic 
methods for the advanced management of arbitrary 'branches'
in extension to RCF6902, and additional methods strictly 
compliant to RFC6902.

Due to the pure in-memory support and addressing by the enclosed 
module JSONPointer for RFC6901 compliant addressing by in memory
caching, the JSONData may outperform designs based on 
operation on the native JSON representation.

Attributes:
    **data**: The data tree of JSON based objects provided
        by the module 'json'.
    **schema**: The validator for 'data' provided by 
        the module 'jsonschema'.

Common call parameters provided by the methods of this class are:
    *targetnode := addressreference*
        The target node of called method. The 'targetnode' in general 
        represents the target of the called method. In most cases this
        has to be a reference to a container for the modification 
        and/or insertion of resulting elements. The methods require
        the change of contained items, which involves the application
        of a 'key' pointing to the hook in point of the reference
        to the modification.
        
    *key := key-value* 
        The hook-in point for references of modified entries within
        the targetnode container. The following values are supported:
                   
    *sourcenode := addressreference*
        The in-memory node address of the source branch for the method,
        e.g. 'copy' or 'move' operation.

The address references supported in this class refer the resulting
in-memory representation of a pointer path. The target is a node 
within a Python data representation as provided by the package 
'**json**' and compatible packages, e.g. '**ujson**'. The supported input
syntax is one of the following interchangeable formats::
    
    # The reference to a in-memory-node.
    addressreference := (
          nodereference
        | addressreference-source
    )

    nodereference:= (
          <in-memory>
        | ''
    )
    
    <in-memory> := "Memory representation of a JSON node, a 'dict'
        or a 'list'. The in-memory Python node reference has to be
        located within the document, due to performance reasons this
        is not verified by default.
        
        The 'nodereference' could be converted from the
        'addressreference-source' representation."

    '' := "Represents the whole document in accordance to RFC6901.
        Same as 'self.data'." 
    
    # The source of the syntax for the description of the reference
    # pointer path to a node. This is applicable on paths to be created.
    addressreference-source := (
        JSONPointer
    )
          
    JSONPointer:="A JSONPointer object in accordance to RFC6901.
        for additional information on input formats refer to the 
        class documentation.
        This class provides a fully qualified path pointer, which
        could be converted into any of the required representations."

For hooks by 'key-value' within addressed containers::

    key-value:=(None|<list-index>|<dict-key>) 
        
    None := "When the 'key' parameter is 'None', the action 
        optionally could be based on the keys of the 'sourcenode'.  
        The contents of the branch replace the node contents
        when the type of the branch matches the hook."

    <list-index>:=('-'|int)
    
    <dict-key>:="Valid for a 'dict' only, sets key/value pair, 
        where present is replace, new is created."

    '-' := "Valid for a 'list' only, appends to present."
    
    int := "Valid for a 'list' only, replaces present when
        0 < #int < len(Node)."
   
In the parameter lists of methods used term 'pointer' is either 
an object of class 'JSONPointer', or a list of pointer path 
entries.

The JSON types 'object' and 'array' behave in Python slightly 
different in accordance to RFC6902. The main difference arise 
from the restrictions on applicable key values. Whereas the
ranges are limited logically by the actual container sizes, 
the object types provide free and unlimited keys. The limit 
is set by type restriction to unicode and 'non-nil' only 
for keys.  

Instance Methods [hide private]
 
__init__(self, *args, **kargs)
Loads and validates a JSON definition with the corresponding schema file.
source code
 
__add__(self, x)
Adds the structure 'x' to 'self', performs deep-operation.
source code
 
__and__(self)
Gets the intersection of 'x' and 'self', performs deep-operation.
source code
 
__call__(self, x)
Evaluates the pointed value from the document.
source code
 
__eq__(self, x)
Compares this JSONData.data with x.
source code
 
__iadd__(self, x)
Adds the structure 'x' to 'self', performs deep-operation.
source code
 
__iand__(self)
Gets the intersection of 'x' and 'self', performs deep-operation.
source code
 
__imod__(self, x)
Returns the difference-modulo-set.
source code
 
__imul__(self, x)
Duplicates the elements of 'self' 'x' times.
source code
 
__mul__(self, x)
Duplicates the elements of 'self' 'x' times.
source code
 
__ior__(self, x)
Returns the superset of branches and attributes.
source code
 
__isub__(self, x)
Returns the residue of X after each present element of 'x' is removed.
source code
 
__ixor__(self, x)
Returns the elements present in one only.
source code
 
__mod__(self, x)
Returns the difference-modulo-set.
source code
 
__radd__(self, x)
Adds the structure 'x' to 'self', performs deep-operation.
source code
 
__rand__(self)
Gets the intersection of 'x' and 'self', performs deep-operation.
source code
 
__rmod__(self, x)
Returns the difference-modulo-set.
source code
 
__rmul__(self, x)
Duplicates the elements of 'self' 'x' times.
source code
 
__or__(self, x)
Returns the superset of branches and attributes.
source code
 
__ror__(self, x)
Returns the superset of branches and attributes.
source code
 
__rsub__(self, x)
Returns the residue of X after each present element of 'x' is removed.
source code
 
__rxor__(self, x)
Returns the elements present in one only.
source code
 
__sub__(self, x)
Returns the residue of X after each present element of 'x' is removed.
source code
 
__xor__(self)
Returns the structure elements present in in one only.
source code
 
__repr__(self)
Dump data.
source code
 
__str__(self)
Dumps data by pretty print.
source code
 
__getitem__(self, key)
Support of slices, for 'iterator' refer to self.__iter__.
source code
 
__iter__(self)
Provides an iterator for data.
source code
 
__ne__(self, x)
Compares this JSONData with x.
source code
 
branch_add(self, targetnode, key, sourcenode)
Add a complete branch into a target structure of type object.
source code
 
branch_copy(self, targetnode, key, sourcenode, force=True)
Copies the source branch to the target node.
source code
 
branch_create(self, targetnode, branch, value=None)
Creates a branch located at targetnode.
source code
 
branch_move(self, targetnode, key, sourcenode, skey, force=True, forcext=False)
Moves a source branch to target node.
source code
 
branch_remove(self, targetnode, key)
Removes a branch from a target structure.
source code
 
branch_replace(self, targetnode, key, sourcenode)
Replaces the value of the target node by the copy of the source branch.
source code
 
getData(self)
Returns the reference to data.
source code
 
getSchema(self)
Returns the reference to schema.
source code
 
getCanonical(self, value)
Fetches the canonical value.
source code
 
isApplicable(self, targetnode, key, branch, matchcondition=None, **kargs)
Checks applicability by validation of provided match criteria.
source code
 
pop(self, key)
Transparently passes the 'pop()' call to 'self.data'.
source code
 
printData(self, pretty=True, **kargs)
Prints structured data.
source code
 
printSchema(self, pretty=True, **kargs)
Prints structured schema.
source code
 
setSchema(self, schemafile=None, targetnode=None, **kargs)
Sets schema or inserts a new branch into the current assigned schema.
source code
 
validate(self, data, schema, validator=None)
Validate data with schema by selected validator.
source code
Class Methods [hide private]
 
branch_test(cls, targetnode, value)
Tests match in accordance to RFC6902.
source code
 
getTreeDiff(cls, n0, n1, difflst=None, alldifs=False, dl=0, path='')
Recursive tree compare for Python trees as used for the package 'json'.
source code
 
getPointerPath(cls, node, base, restype=1)
Converts a node address into the corresponding pointer path.
source code
Class Variables [hide private]
  FIRST = 1
First match only.
  ALL = 3
All matches.
Method Details [hide private]

__init__(self, *args, **kargs)
(Constructor)

source code 
Loads and validates a JSON definition with the corresponding schema file.

Args:
    args*: Optional position parameters, these branch_replace corresponding key
         parameters.
        data
        
    **kargs:
        data: JSON data within memory.
            
            default:= None
        indent_str: Defied the indentation of 'str'.
            
            default:= 4
        interactive: Hints on command line call for optional change of display format. 
            
            default:= False
        schema: A valid in-meory JSONschema.
            
            default:= None
        validator: [default, draft3, draft4, on, off, ]
            Sets schema validator for the data file.
            The values are: default=validate, draft3=Draft3Validator,
            off=None
            
            default:= off

        printdata: branch=None
            Pretty print resulting final data of branch.
            
            default:= top
        printschema: branch=None
            Pretty print resulting schema.
            
            default:= top

        debug: Displays extended state data for developers.
            Requires __debug__==True.
        verbose: Extends the amount of the display of 
            processing data.

Returns:
    Results in an initialized object.

Raises:
    NameError:

    JSONDataValue:

    jsonschema.ValidationError:

    jsonschema.SchemaError:

__call__(self, x)
(Call operator)

source code 
Evaluates the pointed value from the document.

Args:
    x: A valid JSONPointer.

Returns:
    The pointed value, or None.

Raises:
    JSONPointerException

__eq__(self, x)
(Equality operator)

source code 
Compares this JSONData.data with x.

Args:
    x: A valid JSONData.

Returns:
    True or False

Raises:
    JSONDataException

__mul__(self, x)

source code 
Duplicates the elements of 'self' 'x' times.

The operations::

   z = S * x

Returns the remaining subset of: 

   z = S - 1 * x

where '1*x' is for each present element of 'x'. When multiple exist
'n-1' remain.

__mod__(self, x)

source code 
Returns the difference-modulo-set.

The operations::

   z = S % x

Returns the remaining subset of: 

   z = S - n * x

where 'n*x' is the maximum number of present branches 'x'. When
multiple exist, all matching are removed.

__sub__(self, x)
(Subtraction operator)

source code 
Returns the residue of X after each present element of 'x' is removed.

The operations::

   z = S - x

Returns the remaining subset of: 

   z = S - 1 * x

where '1*x' is for each present element of 'x'. When multiple exist
'n-1' remain.

__ne__(self, x)

source code 
Compares this JSONData with x.

Args:
    x: A valid JSONData.

Returns:
    True or False

Raises:
    JSONDataException

branch_add(self, targetnode, key, sourcenode)

source code 
Add a complete branch into a target structure of type object.

Present previous branches are replaced, non-existent branches are 
added. The added branch is created by a deep copy, thus is completely 
independent from the source. 

   Call: *branch_add* ( **t**, **k**, **s** )

   +---+------------------+---------+----------------+-----------+
   | i |  target          | source  | add            |           |
   |   +----------+-------+---------+-------+--------+           |
   |   |  t       | k     | s       | from  | to     | type      |
   +===+==========+=======+=========+=======+========+===========+
   | 0 |  node    | key   | node    | s     | t[k]   | any       |
   +---+----------+-------+---------+-------+--------+-----------+
   | 1 |  node    | None  | node    | s     | t[*]   | match     |
   +---+----------+-------+---------+-------+--------+-----------+

    0. Use-Case-0: Any source node type is added as 't[k]'.
    
    1. Use-Case-1: The content keys of node 's' are added each
        to the node 't'. Therefore the node types of 's' and 't'
        have to match.
        
        This behaviour is defined in respect to the parameter 
        passing of Python.
         
Args:
    targetnode := nodereference
        Target container node where the branch is to be inserted.
    
    key := key-value
        Hook for the insertion within target node.
    
    sourcenode := nodereference
        Source branch to be inserted into the target tree.

Returns:
    When successful returns 'True', else returns either 'False', or
    raises an exception.

Raises:
    JSONDataNodeType:
    JSONDataKeyError:

branch_copy(self, targetnode, key, sourcenode, force=True)

source code 
Copies the source branch to the target node.

The copy is internally mapped onto the 'branch_add' call, 
thus shares basically the same parameters and behaviour.
Due to the required modification of the target only, the
copy is slightly different from the 'branch_move' call.

   Call: *branch_copy* ( **t**, **k**, **s** )

   +---+------------------+---------+----------------+-----------+
   | i |  target          | source  | copy           |           |
   |   +----------+-------+---------+-------+--------+           |
   |   |  t       | k     | s       | from  |  to    | type      |
   +===+==========+=======+=========+=======+========+===========+
   | 0 |  node    | key   | node    | s     | t[k]   | any       |
   +---+----------+-------+---------+-------+--------+-----------+
   | 1 |  node    | None  | node    | s     | t[sk]  | match     |
   +---+----------+-------+---------+-------+--------+-----------+

    For the description of the Use-Cases refer to branch_add.

Args:
    targetnode := nodereference
        Target tree the branch is to be inserted.
    
    key := key-value
        Key of insertion point within target node.
    
    sourcenode := nodereference
        Source branch to be inserted into target tree.
    
    force: If true present are replaced, else only non-present 
        are copied.
        
        default:=True

Returns:
    When successful returns 'True', else returns either 'False', or
    raises an exception.

Raises:
    JSONData:

branch_create(self, targetnode, branch, value=None)

source code 
Creates a branch located at targetnode.

The requested branch as created as child value of provided 
'targetnode'. 'targetnode' is required to exist.
 
**REMARK**: Current version relies for the created nodes on the
    content type of the key(str,unicode)/index(int), later 
    versions may use a provided schema.

   Call: *branch_create* ( **t**, **b**, **v** )

   +---+----------+---------+-------+
   | i |  target  | branch  | value |
   |   +----------+---------+-------+
   |   |  t       | b       | v     |
   +===+==========+=========+=======+
   | 0 |  node    | list    | [any] |
   +---+----------+---------+-------+
   | 1 |  node    | list    | [any] |
   +---+----------+---------+-------+
   | 2 |  node    | pointer | [any] |
   +---+----------+---------+-------+
   | 3 |  node    | pointer | [any] |
   +---+----------+---------+-------+


Args:
    targetnode := nodereference
        Base node for the insertion of branch.

    branch :=  addressreference-source
        New branch to be created in the target tree.
        A Pointer address path relative to the 'targetnode'. 

    value: Optional value for the leaf. The value itselfn
        could be either an atomic type, or a branch itself
        in accordance to RFC6902. 

Returns:
    When successful returns the leaf node, else returns either 
    'None', or raises an exception.

Raises:
    JSONData:

branch_move(self, targetnode, key, sourcenode, skey, force=True, forcext=False)

source code 
Moves a source branch to target node.

Moves by default only when target is not yet present. The
parameters for 'list', 'force' enabled to overwrite, whereas 
the parameter 'forcext' enables to move all entries and 
extend the target items.

Due to the Python specific passing of flat parameters as
a copy of the reference without access to the actual source
entry, these are slightly different from the 'branch_copy'
and 'branch_add' methods modifying the target only. Therefore 
additional source keys 'skey' are required by 'move' in order
to enable the modification of the source entry. 

   Call: *branch_move* ( **t**, **k**, **s**, **sk** )

   +---+------------------+-----------------+---------------+-------+
   | i |  target          | source          | move          |       |
   |   +----------+-------+---------+-------+-------+-------+       |
   |   |  t       | k     | s       | sk    | from  |  to   | type  |
   +===+==========+=======+=========+=======+=======+=======+=======+
   | 0 |  node    | key   | node    | key   | s[sk] | t[k]  | any   |
   +---+----------+-------+---------+-------+-------+-------+-------+
   | 1 |  node    | None  | node    | key   | s[sk] | t[sk] | match |
   +---+----------+-------+---------+-------+-------+-------+-------+

   0. Use-Case-0: Moves any.

   1. Use-Case-1: Moves matching key types only: list-to-list, 
       or dict-to-dict.

Args:
    targetnode := nodereference
        Target tree the branch is to be inserted.
    
    key := key-value
        Key of insertion point within target node.
    
    sourcenode := nodereference
        Source branch to be inserted into target tree.
    
    skey := key-value
        Key of the source to be moved to target node.

    force: If true present are replaced, else only 
        non-present are moved.
        
        default:=True

    forcext: If true target size will be extended when 
        required. This is applicable on 'list' only, and
        extends RFC6902. The same effect is given for 
        a 'list' by one of:
         
        * key:='-' 

        * key:=None and skey:='-'

Returns:
    When successful returns 'True', else returns either 
    'False', or raises an exception.

Raises:
    JSONData:
    JSONDataKey:
    KeyError:

branch_remove(self, targetnode, key)

source code 
Removes a branch from a target structure.

The corresponding elements of the 'targetnode' tree are removed.
The remaining are kept untouched. For tree nodes as leafs the whole
corresponding subtree is deleted.

REMARK: No reference checks are done, so the user is responsible
    for additional references.

   Call: *branch_remove* ( **t**, **k** )

   +---+------------------+--------+-------+
   | i |  target          | remove |       |
   |   +----------+-------+--------+       |
   |   |  t       | k     | branch | type  |
   +===+==========+=======+========+=======+
   | 0 |  node    | key   | t[k]   | any   |
   +---+----------+-------+--------+-------+
   | 1 |  node    | None  | t[*]   | any   |
   +---+----------+-------+--------+-------+

   0. Use-Case-0: Removes any type of node.

   1. Use-Case-1: Removes all contained items of any type.

Args:
    targetnode := nodereference
        Container of 'targetnode' with items to be removed.

    key := key-value
        The item to be removed from the 'targetnode'.
        When 'None', all contained items are removed.

Returns:
    When successful returns 'True', else returns either 'False', or
    raises an exception.

Raises:
    JSONDataException:

branch_replace(self, targetnode, key, sourcenode)

source code 
Replaces the value of the target node by the copy of the source branch.

Requires in order to RFC6902, all items to be replaced has to be
present. Thus fails if at least one is missing.

Internally the 'branch_add()' call is used with a deep copy.
When a swallow copy is required the 'branch_move()' has to be used. 

Args:
    targetnode := nodereference
        Target tree the branch is to be inserted.
    
    key := key-value
        Key of insertion point within target node.
        If key==None, the whole set of keys is replaced by
        the content of the 'sourcenode'.
    
    sourcenode := nodereference
        Source branch to be inserted into target tree.
    
    force: If true present are replaced, else only non-present 
        are copied.

Returns:
    When successful returns 'True', else returns either 'False', or
    raises an exception.

Raises:
    JSONData:

branch_test(cls, targetnode, value)
Class Method

source code 
Tests match in accordance to RFC6902.

Args:
    targetnode := a valid node
        Node to be compared with the value. Due to
        ambiguity the automated conversion is not 
        reliable, thus it has to be valid. 

    value: Expected value for the given node.
    
Returns:
    When successful returns 'True', else returns 'False'.

Raises:
    JSONData:

getTreeDiff(cls, n0, n1, difflst=None, alldifs=False, dl=0, path='')
Class Method

source code 

Recursive tree compare for Python trees as used for the package 'json'.

Finds diff in native Python trees assembled by the standard package 'json' and compatible, e.g. 'ujson'.

getPointerPath(cls, node, base, restype=1)
Class Method

source code 
Converts a node address into the corresponding pointer path.

The current implementation is search based, thus may have 
performance issues when frequently applied.

Args:
    node: Address of Node to be searched for.
    
    base: A tree top nodes to search for node.
    
    restype: Type of search.
        
        first: The first match only. 
        
        all: All matches.
    
Returns:
    Returns a list of lists, where the contained lists are pointer 
    path-lists for matched elements.
    
    * restype:=FIRST: '[[<first-match>]]',
    
    * restype:=ALL: '[[<first-match>],[<second-match>],...]'

Raises:
    JSONData:

getCanonical(self, value)

source code 
Fetches the canonical value.

The actual value could be either an atomic value, a node 
representing a branch, or a reference to an atomic value.
 
Args:
    value: Value pointer to be evaluated to the actual value.
        Valid input types are:
            int,str,unicode: Integer, kept as an atomic integer 
                value.
            dict,list: Assumed to be a valid node for 'json' 
                package, used by reference.

            JSONPointer: A JSON pointer in accordance to 
                RFC6901.

Returns:
    When successful returns the value, else returns either 'False', or
    raises an exception.

Raises:
    JSONData:

isApplicable(self, targetnode, key, branch, matchcondition=None, **kargs)

source code 
Checks applicability by validation of provided match criteria.

The contained data in 'datafile' could be either the initial data
tree, or a new branch defined by a fresh tree structure. The
'targetnode' defines the parent container where the new branch has
to be hooked-in.

Args:
    targetnode:
        Target container hook for the inclusion of the loaded branch.
        The branch is treated as a child-branch, hooked into the
        provided container 'targetnode'.
    branch:
        Branch to be imported into the target container. The branch
        is treated as a child-branch.
    matchcondition:
        Defines the criteria for comparison of present child nodes
        in the target container. The value is a list of critarias
        combined by logical AND. The criteria may vary due to
        the requirement and the type of applied container:
        - common: Common provided criteria are:
            - insert: Just checks whether the branch could be inserted.
                In case of 'list' by 'append', in case of a 'dict' by
                the insert-[]-operator.
                This is in particular foreseen for the initial creation
                of new nodes.
            - present: Checks whether all are present.
            - no: Inverts the match criteria for the whole current set.
        - dict: The provided criteria are:
            - key: Both share the same key(s).
            - child_attr_list: A list of child attributes to be matched.
                This may assure e.g. compatibility by a user defined ID,
                and or a UUID.
            
            default:=['key',]
        - list: The provided criteria are:
            - index: The positions of source and target have to match.
            - child_attr_list: A list of child attributes to be matched,
                thus e.g. the 'key' of dictionaries could be emulated
                by an arbitrary attribute like 'mykey'.
                This may assure e.g. compatibility by a user defined ID,
                and or a UUID.
            - mem: Checks whether the in-memory element is already present.
                Even though this is a quite weak criteria, it is probably
                the only and one common generic criteria for lists.
            
            default:= mem # ATTENTION: almost any call adds a branch!
    **kargs:
        childattrlist: A list of user defined child attributes which
            all together(AND) define the match criteria.
            
            default:=None, returns 'True'
Returns:
    When successful returns 'True', else returns either 'False', or
    raises an exception.

    The rule of thumb is:
        - type-mismatch: Exception
        - value-mismatch: return False

    Success is: no-defined-condition or no-failing-condition

Raises:
    JSONData:

    JSONDataValue:

printData(self, pretty=True, **kargs)

source code 
Prints structured data.

Args:
    pretty: Activates pretty printer for treeview, else flat.

    sourcefile: Loads data from 'sourcefile' into 'source'.
        
        default:=None
    source: Prints data within 'source'.
        
        default:=self.data

Returns:
    When successful returns 'True', else returns either 'False', or
    raises an exception.

Raises:
    JSONDataAmbiguity:

    forwarded from 'json'

printSchema(self, pretty=True, **kargs)

source code 
Prints structured schema.

Args:
    pretty: Activates pretty printer for treeview, else flat.

    sourcefile: Loads schema from 'sourcefile' into 'source'.
        
        default:=None
    source: Prints schema within 'source'.
        
        default:=self.schema

Returns:
    When successful returns 'True', else returns either 'False', or
    raises an exception.

Raises:
    JSONDataAmbiguity:

    forwarded from 'json'

setSchema(self, schemafile=None, targetnode=None, **kargs)

source code 
Sets schema or inserts a new branch into the current assigned schema.

The main schema(targetnode==None) is the schema related to the current
instance. Additional branches could be added by importing the specific
schema definitions into the main schema. These could either kept
volatile as a temporary runtime extension, or stored into a new schema
file in order as extension of the original for later combined reuse.

Args:
    schemafile:
        JSON-Schema filename for validation of the subtree/branch.
        See also **kargs['schema'].
    targetnode:
        Target container hook for the inclusion of the loaded branch.
    **kargs:
        schema:
            In-memory JSON-Schema as an alternative to schemafile.
            When provided the 'schemafile' is ignored.
            
            default:=None
        validator: [default, draft3, off, ]
            Sets schema validator for the data file.
            The values are: default=validate, draft3=Draft3Validator,
            off=None.
            
            default:= validate
        persistent:
            Stores the 'schema' persistently into 'schemafile' after
            completion of update including addition of branches.
            Requires valid 'schemafile'.
            
            default:=False

Returns:
    When successful returns 'True', else returns either 'False', or
    raises an exception.

Raises:

    JSONData:

    JSONDataSourceFile:

    JSONDataValue:

validate(self, data, schema, validator=None)

source code 
Validate data with schema by selected validator.

Args:
    data:
        JSON-Data.
    schema:
        JSON-Schema for validation.
    validator:
        Validator to be applied, current supported:
        
        schema:
            In-memory JSON-Schema as an alternative to schemafile.
            When provided the 'schemafile' is ignored.
            
            default:=None
        validator: [default, draft3, draft4, off, on, ]
            default|MODE_SCHEMA_ON
                The current default.
            draft3|MODE_SCHEMA_DRAFT3
                The first supported JSONSchema IETF-Draft.
            draft4|MODE_SCHEMA_DRAFT4
                The current supported JSONSchema IETF-Draft.
            off|MODE_SCHEMA_OFF:
                No validation.

            Sets schema validator for the data file.
            
            default:= MODE_SCHEMA_DRAFT4

Returns:
    When successful returns 'True', else returns either 'False', or
    raises an exception.

Raises:
    ValidationError:
    SchemaError:
    JSONDataValue: