Skip to content

API Reference

This comprehensive API reference is automatically generated from the source code docstrings using mkdocstrings. All classes, methods, and functions are documented with complete parameter descriptions, return values, and usage examples following NumPy documentation standards.


Package Overview

The jsonanatomy package provides a comprehensive suite of tools for JSON data structure exploration, safe navigation, and analysis. All primary components are available through the main package namespace for convenient access.

jsonanatomy

JSON Anatomy - A Python package for exploring and navigating JSON structures.

MIGRATION NOTICE

This package was previously named 'json-scout' with import name 'jsonscout'. If you're upgrading from json-scout: 1. Uninstall: pip uninstall json-scout 2. Install: pip install json-anatomy 3. Update imports: import jsonscout → import jsonanatomy

See https://github.com/deamonpog/json-anatomy/blob/main/MIGRATION.md

This package provides tools for introspecting, summarizing, and safely accessing nested JSON data structures. It includes utilities for file handling, safe data access patterns, and unified exploration interfaces.

Classes:

Name Description
Explore : class

Lightweight structural explorer for JSON objects.

Maybe : class

Monadic-style wrapper for safe optional traversal.

Xplore : class

Unified convenience facade combining all exploration tools.

SimpleXML : class

Utility for converting XML to nested dictionary structures.

Functions:

Name Description
get_json_file_paths : function

Find JSON files in a directory using glob patterns.

read_json_file : function

Read and parse JSON files with error handling.

Examples:

>>> import jsonanatomy as ja
>>> data = {'users': [{'name': 'Alice', 'age': 30}]}
>>> explorer = ja.Xplore(data)
>>> name = explorer['users'][0]['name'].value()
>>> print(name)  # 'Alice'

get_json_file_paths

get_json_file_paths(base_path, pattern='*.json')

Find JSON files in a directory using glob patterns.

Parameters:

Name Type Description Default
base_path str

The base directory path to search for JSON files.

required
pattern str

The glob pattern to match files, by default "*.json".

'*.json'

Returns:

Type Description
list of str

A list of absolute file paths to JSON files found in the directory.

Examples:

>>> json_files = get_json_file_paths('/path/to/data')
>>> print(json_files)
['/path/to/data/file1.json', '/path/to/data/file2.json']
>>> custom_files = get_json_file_paths('/path/to/data', 'config*.json')
>>> print(custom_files)
['/path/to/data/config_dev.json', '/path/to/data/config_prod.json']
Source code in src\jsonanatomy\file_reader.py
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
def get_json_file_paths(base_path, pattern="*.json"):
    """
    Find JSON files in a directory using glob patterns.

    Parameters
    ----------
    base_path : str
        The base directory path to search for JSON files.
    pattern : str, optional
        The glob pattern to match files, by default "*.json".

    Returns
    -------
    list of str
        A list of absolute file paths to JSON files found in the directory.

    Examples
    --------
    >>> json_files = get_json_file_paths('/path/to/data')
    >>> print(json_files)
    ['/path/to/data/file1.json', '/path/to/data/file2.json']

    >>> custom_files = get_json_file_paths('/path/to/data', 'config*.json')
    >>> print(custom_files)
    ['/path/to/data/config_dev.json', '/path/to/data/config_prod.json']
    """
    json_files = glob.glob(os.path.join(base_path, pattern))
    return json_files

read_json_file

read_json_file(file_path, encoding='utf-8')

Read and parse a JSON file with error handling.

Parameters:

Name Type Description Default
file_path str

The absolute path to the JSON file to read.

required
encoding str

The file encoding to use when reading, by default "utf-8".

'utf-8'

Returns:

Type Description
dict or list

The parsed JSON data structure.

Raises:

Type Description
FileNotFoundError

If the specified file does not exist.

JSONDecodeError

If the file contents are not valid JSON.

Examples:

>>> data = read_json_file('/path/to/data.json')
>>> print(type(data))
<class 'dict'>
>>> data = read_json_file('/path/to/array.json')
>>> print(type(data))
<class 'list'>
Source code in src\jsonanatomy\file_reader.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def read_json_file(file_path, encoding="utf-8"):
    """
    Read and parse a JSON file with error handling.

    Parameters
    ----------
    file_path : str
        The absolute path to the JSON file to read.
    encoding : str, optional
        The file encoding to use when reading, by default "utf-8".

    Returns
    -------
    dict or list
        The parsed JSON data structure.

    Raises
    ------
    FileNotFoundError
        If the specified file does not exist.
    json.JSONDecodeError
        If the file contents are not valid JSON.

    Examples
    --------
    >>> data = read_json_file('/path/to/data.json')
    >>> print(type(data))
    <class 'dict'>

    >>> data = read_json_file('/path/to/array.json')
    >>> print(type(data))
    <class 'list'>
    """
    if not os.path.exists(file_path):
        raise FileNotFoundError(f"File not found at {file_path}")

    with open(file_path, "r", encoding=encoding) as file:
        data = json.load(file)
    return data

Core Modules

File Operations Module

The file_reader module provides essential utilities for locating and loading JSON data files from the filesystem with robust error handling and encoding support.

file_reader

File reader utilities for JSON file operations.

This module provides utility functions for finding and reading JSON files from the filesystem with proper error handling.

get_json_file_paths

get_json_file_paths(base_path, pattern='*.json')

Find JSON files in a directory using glob patterns.

Parameters:

Name Type Description Default
base_path str

The base directory path to search for JSON files.

required
pattern str

The glob pattern to match files, by default "*.json".

'*.json'

Returns:

Type Description
list of str

A list of absolute file paths to JSON files found in the directory.

Examples:

>>> json_files = get_json_file_paths('/path/to/data')
>>> print(json_files)
['/path/to/data/file1.json', '/path/to/data/file2.json']
>>> custom_files = get_json_file_paths('/path/to/data', 'config*.json')
>>> print(custom_files)
['/path/to/data/config_dev.json', '/path/to/data/config_prod.json']
Source code in src\jsonanatomy\file_reader.py
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
def get_json_file_paths(base_path, pattern="*.json"):
    """
    Find JSON files in a directory using glob patterns.

    Parameters
    ----------
    base_path : str
        The base directory path to search for JSON files.
    pattern : str, optional
        The glob pattern to match files, by default "*.json".

    Returns
    -------
    list of str
        A list of absolute file paths to JSON files found in the directory.

    Examples
    --------
    >>> json_files = get_json_file_paths('/path/to/data')
    >>> print(json_files)
    ['/path/to/data/file1.json', '/path/to/data/file2.json']

    >>> custom_files = get_json_file_paths('/path/to/data', 'config*.json')
    >>> print(custom_files)
    ['/path/to/data/config_dev.json', '/path/to/data/config_prod.json']
    """
    json_files = glob.glob(os.path.join(base_path, pattern))
    return json_files

read_json_file

read_json_file(file_path, encoding='utf-8')

Read and parse a JSON file with error handling.

Parameters:

Name Type Description Default
file_path str

The absolute path to the JSON file to read.

required
encoding str

The file encoding to use when reading, by default "utf-8".

'utf-8'

Returns:

Type Description
dict or list

The parsed JSON data structure.

Raises:

Type Description
FileNotFoundError

If the specified file does not exist.

JSONDecodeError

If the file contents are not valid JSON.

Examples:

>>> data = read_json_file('/path/to/data.json')
>>> print(type(data))
<class 'dict'>
>>> data = read_json_file('/path/to/array.json')
>>> print(type(data))
<class 'list'>
Source code in src\jsonanatomy\file_reader.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def read_json_file(file_path, encoding="utf-8"):
    """
    Read and parse a JSON file with error handling.

    Parameters
    ----------
    file_path : str
        The absolute path to the JSON file to read.
    encoding : str, optional
        The file encoding to use when reading, by default "utf-8".

    Returns
    -------
    dict or list
        The parsed JSON data structure.

    Raises
    ------
    FileNotFoundError
        If the specified file does not exist.
    json.JSONDecodeError
        If the file contents are not valid JSON.

    Examples
    --------
    >>> data = read_json_file('/path/to/data.json')
    >>> print(type(data))
    <class 'dict'>

    >>> data = read_json_file('/path/to/array.json')
    >>> print(type(data))
    <class 'list'>
    """
    if not os.path.exists(file_path):
        raise FileNotFoundError(f"File not found at {file_path}")

    with open(file_path, "r", encoding=encoding) as file:
        data = json.load(file)
    return data

Structural Exploration Module

The Explore class offers lightweight structural analysis capabilities for JSON objects, enabling inspection of nested hierarchies and statistical analysis of data schemas.

Explore

Lightweight structural explorer for JSON objects.

This module provides the Explore class for basic inspection and navigation of nested JSON data structures (dictionaries and lists).

Explore

Explore(json_object)

A lightweight explorer for inspecting JSON object structures.

This class provides methods to examine the structure of JSON data, navigate through nested objects, and analyze the distribution of child properties across collections.

Parameters:

Name Type Description Default
json_object dict, list, or any

The JSON object to explore. Can be a dictionary, list, or any other type.

required

Attributes:

Name Type Description
data dict, list, or any

The original JSON object being explored.

child_keys list

A list of keys (for dicts) or indices (for lists) of direct children.

Examples:

>>> data = {'users': [{'name': 'Alice'}, {'name': 'Bob'}]}
>>> explorer = Explore(data)
>>> print(explorer.get_child_keys())
['users']
>>> users_explorer = explorer.explore_child('users')
>>> print(users_explorer.get_child_keys())
[0, 1]
Source code in src\jsonanatomy\Explore.py
39
40
41
42
43
44
45
def __init__(self, json_object):
    self.data = json_object
    self.child_keys = []
    if type(self.data) is dict:
        self.child_keys = list(self.data.keys())
    if type(self.data) is list:
        self.child_keys = [idx for idx in range(len(self.data))]

child

child(child_key)

Create a new Explore instance for a specific child.

Parameters:

Name Type Description Default
child_key str or int

The key (for dict) or index (for list) of the child to explore.

required

Returns:

Type Description
Explore

A new Explore instance wrapping the child object, or None if not found.

Examples:

>>> data = {'users': [{'name': 'Alice'}]}
>>> explorer = Explore(data)
>>> child = explorer.child('users')
>>> print(type(child.data))
<class 'list'>
Source code in src\jsonanatomy\Explore.py
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
def child(self, child_key):
    """
    Create a new Explore instance for a specific child.

    Parameters
    ----------
    child_key : str or int
        The key (for dict) or index (for list) of the child to explore.

    Returns
    -------
    Explore
        A new Explore instance wrapping the child object, or None if not found.

    Examples
    --------
    >>> data = {'users': [{'name': 'Alice'}]}
    >>> explorer = Explore(data)
    >>> child = explorer.child('users')
    >>> print(type(child.data))
    <class 'list'>
    """
    if child_key in self.child_keys:
        return Explore(self.data[child_key])
    return Explore(None)

field_counts

field_counts(verbose=False)

Analyze the distribution of field names across all children in a collection.

This method examines each child of the current object and counts how frequently each field name appears across all children. Useful for understanding the schema of collections with varying structures.

Parameters:

Name Type Description Default
verbose bool

If True, print detailed exploration progress, by default False.

False

Returns:

Type Description
dict

A dictionary mapping field names to their occurrence counts.

Examples:

>>> data = {
...     'users': [
...         {'name': 'Alice', 'age': 30},
...         {'name': 'Bob', 'email': 'bob@example.com'},
...         {'name': 'Charlie', 'age': 25}
...     ]
... }
>>> explorer = Explore(data['users'])
>>> counts = explorer.field_counts()
>>> print(counts)
{'name': 3, 'age': 2, 'email': 1}
Notes

This method is particularly useful for analyzing collections where objects may have varying schemas or optional properties.

Source code in src\jsonanatomy\Explore.py
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
def field_counts(self, verbose=False):
    """
    Analyze the distribution of field names across all children in a collection.

    This method examines each child of the current object and counts
    how frequently each field name appears across all children.
    Useful for understanding the schema of collections with varying structures.

    Parameters
    ----------
    verbose : bool, optional
        If True, print detailed exploration progress, by default False.

    Returns
    -------
    dict
        A dictionary mapping field names to their occurrence counts.

    Examples
    --------
    >>> data = {
    ...     'users': [
    ...         {'name': 'Alice', 'age': 30},
    ...         {'name': 'Bob', 'email': 'bob@example.com'},
    ...         {'name': 'Charlie', 'age': 25}
    ...     ]
    ... }
    >>> explorer = Explore(data['users'])
    >>> counts = explorer.field_counts()
    >>> print(counts)
    {'name': 3, 'age': 2, 'email': 1}

    Notes
    -----
    This method is particularly useful for analyzing collections where
    objects may have varying schemas or optional properties.
    """
    if verbose:
        print(f"Exploring grandchildren of type: {type(self.child_keys)} (size={len(self.data)}) with keys: {self.keys()}")
    counts = {}
    for child_key in self.child_keys:
        if verbose:
            print(f"Exploring child key: {child_key}")
        expChild = self.child(child_key)
        if verbose:
            print(f"  Child type: {type(expChild.data)} with keys: {expChild.keys()}")
        for grandChildKey in expChild.keys():
            if verbose:
                print(f"    Found grandchild key: {grandChildKey}")
            if grandChildKey in counts:
                counts[grandChildKey] += 1
            else:
                counts[grandChildKey] = 1

    return counts

keys

keys()

Get the keys or indices of direct children.

Returns:

Type Description
list

For dictionaries: list of string keys. For lists: list of integer indices. For other types: empty list.

Examples:

>>> data = {'a': 1, 'b': 2}
>>> explorer = Explore(data)
>>> print(explorer.keys())
['a', 'b']
>>> data = [10, 20, 30]
>>> explorer = Explore(data)
>>> print(explorer.keys())
[0, 1, 2]
Source code in src\jsonanatomy\Explore.py
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
def keys(self):
    """
    Get the keys or indices of direct children.

    Returns
    -------
    list
        For dictionaries: list of string keys.
        For lists: list of integer indices.
        For other types: empty list.

    Examples
    --------
    >>> data = {'a': 1, 'b': 2}
    >>> explorer = Explore(data)
    >>> print(explorer.keys())
    ['a', 'b']

    >>> data = [10, 20, 30]
    >>> explorer = Explore(data)
    >>> print(explorer.keys())
    [0, 1, 2]
    """
    return self.child_keys

value

value()

Get the underlying data object.

Returns:

Type Description
any

The wrapped data object being explored.

Examples:

>>> data = {'name': 'Alice', 'age': 30}
>>> explorer = Explore(data)
>>> original = explorer.value()  # Returns: {'name': 'Alice', 'age': 30}
>>> assert original is data  # Same object reference
Source code in src\jsonanatomy\Explore.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
def value(self):
    """
    Get the underlying data object.

    Returns
    -------
    any
        The wrapped data object being explored.

    Examples
    --------
    >>> data = {'name': 'Alice', 'age': 30}
    >>> explorer = Explore(data)
    >>> original = explorer.value()  # Returns: {'name': 'Alice', 'age': 30}
    >>> assert original is data  # Same object reference
    """
    return self.data

Safe Access Module

The Maybe class implements a monadic pattern for safe, exception-free navigation through potentially incomplete or malformed JSON structures, supporting chainable operations.

Maybe

Safe access wrapper for JSON data structures.

This module provides the Maybe class, which implements a monadic-style pattern for safely accessing nested JSON data without raising exceptions when keys or indices don't exist.

Maybe

Maybe(json_object)

A wrapper for safe optional traversal over JSON data structures.

The Maybe class provides safe access to fields and indices without raising exceptions when accessing non-existent keys or out-of-bounds indices. This follows a monadic pattern where operations can be chained safely.

Parameters:

Name Type Description Default
json_object any

The JSON object to wrap. Can be a dict, list, or any other type.

required

Attributes:

Name Type Description
data any

The wrapped JSON object that may or may not exist.

Examples:

>>> data = {'name': 'Alice', 'age': 30}
>>> maybe = Maybe(data)
>>> name = maybe.field('name').value()  # 'Alice'
>>> missing = maybe.field('missing').value()  # None
>>> data = [10, 20, 30]
>>> maybe = Maybe(data)
>>> first = maybe.index(0).value()  # 10
>>> out_of_bounds = maybe.index(5).value()  # None
Source code in src\jsonanatomy\Maybe.py
40
41
def __init__(self, json_object):
    self.data = json_object

array

array(func=lambda k, o: o, filter=lambda k, o: True, as_type=list)

Safely convert a JSON array or object to a list of transformed items.

Applies a transformation function to each item in an array or each key-value pair in an object. Items can be filtered before transformation.

Parameters:

Name Type Description Default
func callable

Function to transform each item. For arrays: func(index, value). For objects: func(key, value). Default returns the value unchanged.

lambda k, o: o
filter callable

Function to filter items before transformation. Same signature as func. Default accepts all items.

lambda k, o: True
as_type type

The type constructor for the result container, by default list.

list

Returns:

Type Description
list or as_type

A container of transformed items, or empty container if not applicable.

Examples:

>>> maybe_list = Maybe([1, 2, 3])
>>> doubled = maybe_list.array(lambda k,v: v*2)  # [2, 4, 6]
>>> filtered = maybe_list.array(lambda k,v: v*2, lambda k,v: v > 2)  # [6]
>>> maybe_dict = Maybe({'a': 1, 'b': 2, 'c': 3})
>>> items = maybe_dict.array(lambda k,v: (k, v*2))  # [('a', 2), ('b', 4), ('c', 6)]
>>> filtered = maybe_dict.array(lambda k,v: (k, v*2), lambda k,v: v > 2)  # [('c', 6)]
>>> not_array = Maybe(42).array()  # []
Source code in src\jsonanatomy\Maybe.py
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
def array(self, func=lambda k,o: o, filter=lambda k,o: True, as_type=list):
    """
    Safely convert a JSON array or object to a list of transformed items.

    Applies a transformation function to each item in an array or each 
    key-value pair in an object. Items can be filtered before transformation.

    Parameters
    ----------
    func : callable, optional
        Function to transform each item. For arrays: func(index, value).
        For objects: func(key, value). Default returns the value unchanged.
    filter : callable, optional
        Function to filter items before transformation. Same signature as func.
        Default accepts all items.
    as_type : type, optional
        The type constructor for the result container, by default list.

    Returns
    -------
    list or as_type
        A container of transformed items, or empty container if not applicable.

    Examples
    --------
    >>> maybe_list = Maybe([1, 2, 3])
    >>> doubled = maybe_list.array(lambda k,v: v*2)  # [2, 4, 6]
    >>> filtered = maybe_list.array(lambda k,v: v*2, lambda k,v: v > 2)  # [6]

    >>> maybe_dict = Maybe({'a': 1, 'b': 2, 'c': 3})
    >>> items = maybe_dict.array(lambda k,v: (k, v*2))  # [('a', 2), ('b', 4), ('c', 6)]
    >>> filtered = maybe_dict.array(lambda k,v: (k, v*2), lambda k,v: v > 2)  # [('c', 6)]

    >>> not_array = Maybe(42).array()  # []
    """
    if self.data is not None:
        if type(self.data) is dict:
            return as_type([func(key, obj) for key,obj in self.data.items() if filter(key, obj)])
        elif type(self.data) is list:
            return as_type([func(idx, obj) for idx,obj in enumerate(self.data) if filter(idx, obj)])
    return []

field

field(field)

Safely access a field in a JSON object (dict).

Parameters:

Name Type Description Default
field str

The field name to access in the dictionary.

required

Returns:

Type Description
Maybe

A new Maybe instance wrapping the field value or None if not present.

Examples:

>>> maybe = Maybe({'name': 'Alice'})
>>> name = maybe.field('name').value()  # 'Alice'
>>> age = maybe.field('age').value()    # None
Source code in src\jsonanatomy\Maybe.py
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
def field(self, field):
    """
    Safely access a field in a JSON object (dict).

    Parameters
    ----------
    field : str
        The field name to access in the dictionary.

    Returns
    -------
    Maybe
        A new Maybe instance wrapping the field value or None if not present.

    Examples
    --------
    >>> maybe = Maybe({'name': 'Alice'})
    >>> name = maybe.field('name').value()  # 'Alice'
    >>> age = maybe.field('age').value()    # None
    """
    if self.data is not None and type(self.data) is dict and field in self.data:
        return Maybe(self.data[field])
    return Maybe(None)

filter

filter(func=lambda k, o: True)

Safely filter items in a JSON array or object.

Parameters:

Name Type Description Default
func callable

Function to determine which items to keep. For arrays: func(index, value). For objects: func(key, value). Default keeps all items.

lambda k, o: True

Returns:

Type Description
Maybe

A new Maybe wrapping filtered data of the same type, or None if not applicable.

Examples:

>>> maybe_dict = Maybe({'a': 1, 'b': 2, 'c': 3})
>>> filtered = maybe_dict.filter(lambda k,v: v > 2).value()  # {'c': 3}
>>> maybe_list = Maybe([1, 2, 3, 4])
>>> filtered = maybe_list.filter(lambda i,v: v % 2 == 0).value()  # [2, 4]
Source code in src\jsonanatomy\Maybe.py
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
def filter(self, func=lambda k,o: True):
    """
    Safely filter items in a JSON array or object.

    Parameters
    ----------
    func : callable, optional
        Function to determine which items to keep. For arrays: func(index, value).
        For objects: func(key, value). Default keeps all items.

    Returns
    -------
    Maybe
        A new Maybe wrapping filtered data of the same type, or None if not applicable.

    Examples
    --------
    >>> maybe_dict = Maybe({'a': 1, 'b': 2, 'c': 3})
    >>> filtered = maybe_dict.filter(lambda k,v: v > 2).value()  # {'c': 3}

    >>> maybe_list = Maybe([1, 2, 3, 4])
    >>> filtered = maybe_list.filter(lambda i,v: v % 2 == 0).value()  # [2, 4]
    """
    if self.data is not None:
        if type(self.data) is dict:
            return Maybe({k: v for k,v in self.data.items() if func(k,v)})
        elif type(self.data) is list:
            return Maybe([obj for idx,obj in enumerate(self.data) if func(idx, obj)])
    return Maybe(None)

index

index(index)

Safely access an index in a JSON array (list).

Parameters:

Name Type Description Default
index int

The zero-based index to access in the list.

required

Returns:

Type Description
Maybe

A new Maybe instance wrapping the item value or None if not present.

Examples:

>>> maybe = Maybe([1, 2, 3])
>>> first = maybe.index(0).value()  # 1
>>> fourth = maybe.index(3).value()  # None
Source code in src\jsonanatomy\Maybe.py
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
def index(self, index):
    """
    Safely access an index in a JSON array (list).

    Parameters
    ----------
    index : int
        The zero-based index to access in the list.

    Returns
    -------
    Maybe
        A new Maybe instance wrapping the item value or None if not present.

    Examples
    --------
    >>> maybe = Maybe([1, 2, 3])
    >>> first = maybe.index(0).value()  # 1
    >>> fourth = maybe.index(3).value()  # None
    """
    if self.data is not None and type(self.data) is list and index < len(self.data):
        return Maybe(self.data[index])
    return Maybe(None)

value

value()

Get the wrapped value.

Returns:

Type Description
any

The wrapped data object, which may be None if no value exists.

Examples:

>>> maybe = Maybe({'name': 'Alice'})
>>> data = maybe.value()  # {'name': 'Alice'}
>>> assert data == maybe.data  # Both access methods return same object
>>> empty = Maybe(None)
>>> data = empty.value()  # None
Source code in src\jsonanatomy\Maybe.py
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
def value(self):
    """
    Get the wrapped value.

    Returns
    -------
    any
        The wrapped data object, which may be None if no value exists.

    Examples
    --------
    >>> maybe = Maybe({'name': 'Alice'})
    >>> data = maybe.value()  # {'name': 'Alice'}
    >>> assert data == maybe.data  # Both access methods return same object

    >>> empty = Maybe(None)
    >>> data = empty.value()  # None
    """
    return self.data

XML Processing Module

The SimpleXML class provides efficient XML-to-dictionary conversion capabilities for integrating XML data sources into JSON-based workflows.

SimpleXML

Simple XML to dictionary converter.

This module provides a utility class for parsing XML strings and converting them to nested dictionary structures for easier JSON-like manipulation.

SimpleXML

SimpleXML(xml_string)

A utility class for converting XML strings to nested dictionary structures.

This class provides simple XML parsing capabilities, converting XML elements to nested dictionaries and analyzing tag usage patterns.

Parameters:

Name Type Description Default
xml_string str

The XML string to parse and convert.

required

Attributes:

Name Type Description
xml_string str

The original XML string.

root Element

The parsed XML root element.

Raises:

Type Description
ParseError

If the XML string is malformed or cannot be parsed.

Examples:

>>> xml_data = '<users><user><name>Alice</name><age>30</age></user></users>'
>>> parser = SimpleXML(xml_data)
>>> result = parser.to_dict()
>>> print(result)
{'user': {'name': 'Alice', 'age': '30'}}
Source code in src\jsonanatomy\SimpleXML.py
42
43
44
def __init__(self, xml_string):
    self.xml_string = xml_string
    self.root = ET.fromstring(self.xml_string)

analyze_tag_usagee

analyze_tag_usagee()

Analyze the frequency of XML tags in the document.

Returns:

Type Description
dict

A dictionary mapping tag names to their occurrence counts.

Examples:

>>> xml_data = '<root><item>1</item><item>2</item><name>test</name></root>'
>>> parser = SimpleXML(xml_data)
>>> counts = parser.analyze_tag_usagee()
>>> print(counts)
{'root': 1, 'item': 2, 'name': 1}
Notes

The method name contains a typo ('usagee' instead of 'usage') but is preserved for backward compatibility.

Source code in src\jsonanatomy\SimpleXML.py
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
def analyze_tag_usagee(self):
    """
    Analyze the frequency of XML tags in the document.

    Returns
    -------
    dict
        A dictionary mapping tag names to their occurrence counts.

    Examples
    --------
    >>> xml_data = '<root><item>1</item><item>2</item><name>test</name></root>'
    >>> parser = SimpleXML(xml_data)
    >>> counts = parser.analyze_tag_usagee()
    >>> print(counts)
    {'root': 1, 'item': 2, 'name': 1}

    Notes
    -----
    The method name contains a typo ('usagee' instead of 'usage') but is
    preserved for backward compatibility.
    """
    tag_counts = {}
    self._count_tags(self.root, tag_counts)
    return tag_counts

to_dict

to_dict()

Convert the XML structure to a nested dictionary.

Returns:

Type Description
dict

A nested dictionary representation of the XML structure. Text content becomes string values, and nested elements become nested dictionaries.

Examples:

>>> xml_data = '<person><name>John</name><age>25</age></person>'
>>> parser = SimpleXML(xml_data)
>>> result = parser.to_dict()
>>> print(result)
{'name': 'John', 'age': '25'}
Source code in src\jsonanatomy\SimpleXML.py
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
def to_dict(self):
    """
    Convert the XML structure to a nested dictionary.

    Returns
    -------
    dict
        A nested dictionary representation of the XML structure.
        Text content becomes string values, and nested elements become
        nested dictionaries.

    Examples
    --------
    >>> xml_data = '<person><name>John</name><age>25</age></person>'
    >>> parser = SimpleXML(xml_data)
    >>> result = parser.to_dict()
    >>> print(result)
    {'name': 'John', 'age': '25'}
    """
    return self._element_to_dict(self.root)

Unified Interface Module

The Xplore class serves as a comprehensive facade that combines the functionality of all core modules into a single, intuitive interface for streamlined JSON exploration workflows.

Xplore

Unified convenience facade for JSON exploration.

This module provides the Xplore class, which combines the functionality of Explore, Maybe, and SimpleXML into a single convenient interface for exploring and navigating JSON data structures.

Xplore

Xplore(data)

Unified convenience facade combining exploration tools.

This class provides a single entry point that wires together the functionality of Explore (structural exploration), Maybe (safe access), and SimpleXML (XML parsing) into one convenient interface.

Parameters:

Name Type Description Default
data any

The input data to be explored. Can be JSON data, XML string, or other data types.

required

Attributes:

Name Type Description
data any

The original input data.

explore Explore

An Explore instance for general data exploration.

maybe Maybe

A Maybe instance for safe data access operations.

xml SimpleXML or None

A SimpleXML instance if data is an XML string, None otherwise.

Examples:

>>> data = {'users': [{'name': 'Alice', 'age': 30}]}
>>> xplore = Xplore(data)
>>> name = xplore['users'][0]['name'].value()
>>> print(name)  # 'Alice'
>>> xml_data = '<user><name>Bob</name></user>'
>>> xplore = Xplore(xml_data)
>>> xml_dict = xplore.xml.to_dict()
>>> print(xml_dict)  # {'name': 'Bob'}
Notes
  • Creates an Explore instance for general data exploration
  • Creates a Maybe instance for safe data access operations
  • Creates a SimpleXML instance only if data is a string starting with "<"
  • The xml attribute will be None if data is not XML-formatted
Source code in src\jsonanatomy\Xplore.py
58
59
60
61
62
def __init__(self, data):
    self.data = data
    self.explore = Explore(data)
    self.maybe = Maybe(data)
    self.xml = SimpleXML(data) if isinstance(data, str) and data.strip().startswith("<") else None

keys

keys()

Get the keys of the current data if it's a dictionary or list.

Returns:

Type Description
list

For dictionaries: list of string keys. For lists: list of integer indices. For other types: empty list.

Examples:

>>> data = {'name': 'Alice', 'age': 30}
>>> xplore = Xplore(data)
>>> print(xplore.keys())
['name', 'age']
>>> data = [10, 20, 30]
>>> xplore = Xplore(data)
>>> print(xplore.keys())
[0, 1, 2]
Source code in src\jsonanatomy\Xplore.py
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
def keys(self):
    """
    Get the keys of the current data if it's a dictionary or list.

    Returns
    -------
    list
        For dictionaries: list of string keys.
        For lists: list of integer indices.
        For other types: empty list.

    Examples
    --------
    >>> data = {'name': 'Alice', 'age': 30}
    >>> xplore = Xplore(data)
    >>> print(xplore.keys())
    ['name', 'age']

    >>> data = [10, 20, 30]
    >>> xplore = Xplore(data)
    >>> print(xplore.keys())
    [0, 1, 2]
    """
    return self.explore.keys()

value

value()

Get the underlying data object.

Returns:

Type Description
any

The wrapped data object being explored.

Examples:

>>> data = {'name': 'Alice', 'age': 30}
>>> xplore = Xplore(data)
>>> original = xplore.value()  # Returns: {'name': 'Alice', 'age': 30}
>>> assert original is data  # Same object reference
Source code in src\jsonanatomy\Xplore.py
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
def value(self):
    """
    Get the underlying data object.

    Returns
    -------
    any
        The wrapped data object being explored.

    Examples
    --------
    >>> data = {'name': 'Alice', 'age': 30}
    >>> xplore = Xplore(data)
    >>> original = xplore.value()  # Returns: {'name': 'Alice', 'age': 30}
    >>> assert original is data  # Same object reference
    """
    return self.data