A comprehensive Python library for bidirectional conversion between JSON objects and JSONPath expressions, with advanced features for complex data manipulation, XML processing, JSON merging, and enhanced logging capabilities.
Author
: Yakub Mohammad ([email protected] , [email protected]) , Rishaad ([email protected]) | AR USA LLC
- Bidirectional conversion between JSON objects and JSONPath expressions
- Advanced filter conditions using
extend
parameter for intelligent array handling - Complex nested structures support with proper data integrity
- Array indexing and filtering with conditional expressions
- Error handling and validation for robust JSONPath processing
- Pretty printing with flexible formatting options (
jprint
) - JSON merging with deep merge capabilities and list handling strategies
- XML to JSON conversion with namespace preservation options
- Multi-level logging with console and file output
- Automatic caller information (file name and line number)
- Selective file capture for important messages
- Detailed traceback logging for exception handling
- Dynamic configuration for runtime log file management
pip install jsonpath-nz
Convert JSONPath expressions to a dictionary structure with advanced filtering support.
Parameters:
manifest
(dict): Dictionary with JSONPath expressions as keys and target valuesextend
(dict, optional): Configuration for advanced list merging behavior
Returns:
- dict: Processed dictionary structure or error dictionary
Features:
- Validates JSONPath syntax and bracket balancing
- Supports complex nested structures and arrays
- Handles filter conditions with extend parameter
- Provides detailed error reporting for invalid expressions
Example:
from jsonpath_nz import parse_jsonpath, jprint
# JSONPath expressions with filter conditions
jsonpath_data = {
"$.store.book[1].author": "Yakub Mohammad",
"$.store.local": "False",
"$.channel": "online",
"$.loanApplication.borrower[?(@.firstName == 'John' && @.lastName == 'Doe')].contact": "9876543210",
"$.loanApplication.borrower[?(@.firstName == 'John' && @.lastName == 'wright')].contact": "9876543211"
}
extend = {
"borrower": ["firstName", "lastName"]
}
result = parse_jsonpath(jsonpath_data, extend=extend)
jprint(result)
Output:
{
"store": {
"book": [
{},
{
"author": "Yakub Mohammad"
}
],
"local": "False"
},
"channel": "online",
"loanApplication": {
"borrower": [
{
"firstName": "(John)",
"lastName": "(Doe)",
"contact": "9876543210"
},
{
"firstName": "(John)",
"lastName": "(wright)",
"contact": "9876543211"
}
]
}
}
Convert a dictionary to JSONPath expressions with support for both array indices and filter conditions.
Parameters:
data
(dict): Input dictionary to convert to JSONPath expressionsparent_path
(str, optional): Base JSONPath prefix (defaults to "$")paths
(dict, optional): Dictionary to accumulate results (created if None)extend
(dict, optional): Configuration for filter-based array handling
Returns:
- dict: Dictionary mapping JSONPath expressions to their values
JSONPath Expression Types:
- Simple paths:
$.user.name
for nested values - Array index paths:
$.items[0].price
for array elements - Filter paths:
$.users[?(@.id == '123' && @.active == 'true')].email
Example:
from jsonpath_nz import parse_dict, jprint
# Complex nested dictionary
dict_data = {
"store": {"book": [{"author": "Yakub Mohammad"}, {"category": "Fiction"}]},
"channel": "online",
"loanApplication": {
'borrower': [
{'firstName': 'John', 'lastName': 'Doe', 'contact': '9876543210'},
{'firstName': 'John', 'lastName': 'wright', 'contact': '9876543211'}
]
}
}
extend = {
"borrower": ["firstName", "lastName"]
}
result = parse_dict(dict_data, extend=extend)
jprint(result)
Output:
{
"$.store.book[0].author": "Yakub Mohammad",
"$.store.book[1].category": "Fiction",
"$.channel": "online",
"$.loanApplication.borrower[?(@.firstName == 'John' && @.lastName == 'Doe')].contact": "9876543210",
"$.loanApplication.borrower[?(@.firstName == 'John' && @.lastName == 'wright')].contact": "9876543211"
}
Merge two JSON files or dictionaries with support for nested structures and intelligent list handling.
Parameters:
dict1
(Union[Dict, str]): First dictionary or path to JSON filedict2
(Union[Dict, str]): Second dictionary or path to JSON file (takes precedence)extend
(bool, optional): Controls list merging behavior (defaults to False)
Returns:
- dict: New merged dictionary without modifying originals
List Merging Modes:
extend=False
: Element-wise merging with remaining elements appendedextend=True
: Key-based matching for dictionary items in lists
Example:
from jsonpath_nz import merge_json, jprint
# Basic merging
dict1 = {
"user": {"name": "John", "age": 25},
"settings": {"theme": "dark"}
}
dict2 = {
"user": {"email": "[email protected]", "age": 26},
"settings": {"language": "en"}
}
result = merge_json(dict1, dict2)
jprint(result)
Output:
{
"user": {
"name": "John",
"age": 26,
"email": "[email protected]"
},
"settings": {
"theme": "dark",
"language": "en"
}
}
Convert XML data to JSON format with comprehensive namespace handling and flexible input support.
Parameters:
xml_data
(str or file-like): XML content, file path, or file-like objectnamespace
(bool, optional): Preserve namespaces with prefixes (defaults to True)
Returns:
- str: Pretty-printed JSON string with UTF-8 support
Input Types Supported:
- XML strings (content starting with '<?xml' or '<')
- File paths to XML files
- File-like objects with read() method
Namespace Handling:
namespace=True
: Preserves namespaces as prefixes (e.g., "ns0:elementName")namespace=False
: Strips namespaces, keeping only local names
Example:
from jsonpath_nz import xml_to_json
xml_string = '''<?xml version="1.0"?>
<catalog xmlns:lib="http://library.org">
<lib:book id="1">
<title>XML Guide</title>
<author>John Doe</author>
<price>29.99</price>
</lib:book>
</catalog>'''
# With namespace preservation
result_with_ns = xml_to_json(xml_string, namespace=True)
print("With namespaces:")
print(result_with_ns)
# Without namespaces
result_without_ns = xml_to_json(xml_string, namespace=False)
print("\nWithout namespaces:")
print(result_without_ns)
Pretty-print data in JSON format with flexible input handling and formatting options.
Parameters:
data
(Any): Data to print (dict, list, string, or any object)load
(bool, optional): Parse string input as JSON (defaults to False)marshall
(bool, optional): Convert non-serializable objects to strings (defaults to True)indent
(int, optional): JSON indentation spaces (defaults to 2)
Features:
- Handles various input types automatically
- Graceful fallback for serialization errors
- Custom object conversion with marshalling
- Consistent JSON formatting
Example:
from jsonpath_nz import jprint
from datetime import datetime
# Pretty print with custom objects
data = {
"timestamp": datetime.now(),
"items": [1, 2, 3],
"user": {"name": "John", "active": True}
}
jprint(data, indent=4) # Custom indentation
The library includes a sophisticated logging system with automatic caller information and selective file capture.
Enhanced logging configuration with file capture and caller information.
Features:
- Automatic file name and line number inclusion
- Conditional file capture with capture parameter
- Enhanced traceback logging
- Runtime configuration updates
log.debug(msg, *args, **kwargs)
- Detailed debugging informationlog.info(msg, *args, **kwargs)
- General program informationlog.warning(msg, *args, **kwargs)
- Warning messageslog.error(msg, *args, **kwargs)
- Error messageslog.critical(msg, *args, **kwargs)
- Critical system errorslog.traceback(exc_info=None)
- Detailed exception logginglog.config(log_file_path=None)
- Runtime configuration
Capture Options:
- Keyword argument:
log.info("Message", capture=True)
- Positional flag:
log.error("Error occurred", 1)
Example:
from jsonpath_nz import log
# Configure log file (optional)
log.config("application.log")
# Basic logging (console only)
log.info("Application started")
log.debug("Processing data")
# Logging with file capture
log.warning("Configuration issue detected", capture=True)
log.error("Database connection failed", 1) # Using positional flag
# Exception handling with traceback
try:
result = 1 / 0
except Exception as e:
log.traceback(e) # Automatically captures to file
log.error("Division by zero error occurred", capture=True)
Output Format:
2025-01-05 10:30:45,123 - INFO [main.py:15] Application started
2025-01-05 10:30:45,124 - DEBUG [main.py:16] Processing data
2025-01-05 10:30:45,125 - WARNING [main.py:19] Configuration issue detected
2025-01-05 10:30:45,126 - ERROR [main.py:20] Database connection failed
2025-01-05 10:30:45,127 - ERROR [main.py:26] ======= TRACEBACK =======
Traceback (most recent call last):
File "main.py", line 23, in <module>
result = 1 / 0
ZeroDivisionError: division by zero
The extend parameter enables sophisticated filtering and merging strategies for array elements:
extend_config = {
"array_field_name": ["filter_field1", "filter_field2"],
"users": ["id", "email"],
"products": ["sku", "category"]
}
Filter Behavior:
- Fields listed in extend become filter conditions
- Remaining fields become target paths
- Multiple filter fields combined with AND logic
- Creates JSONPath expressions like:
$.users[?(@.id == 'value' && @.email == '[email protected]')].name
All functions include comprehensive error handling:
- parse_jsonpath: Returns
{"error": "description"}
for invalid JSONPath expressions - parse_dict: Graceful handling of mixed data types and invalid structures
- merge_json: File access and JSON parsing error handling
- xml_to_json: XML parsing and conversion error handling with detailed messages
- Logging: Built-in exception handling with fallback behavior
- Memory Usage: Functions process data entirely in memory
- Large Files: Consider memory constraints for very large JSON/XML files
- Namespace Processing: XML namespace extraction may parse files twice
- Deep Nesting: Recursive processing handles deeply nested structures efficiently
- JSONPath Validation: Always check return values for error dictionaries
- Extend Configuration: Use extend parameter for intelligent array handling
- Namespace Handling: Choose appropriate namespace mode for XML conversion
- Logging Capture: Use selective file capture for important messages only
- Error Handling: Implement proper error checking in production code
The library includes comprehensive test suites:
tests/test_parse_jsonpath.py
- JSONPath to dictionary conversion teststests/test_parse_dict.py
- Dictionary to JSONPath conversion teststests/test_merge_json.py
- JSON merging functionality teststests/test_xml_to_json.py
- XML to JSON conversion teststests/test_log.py
- Enhanced logging system teststests/test_jprint.py
- Pretty printing utility tests
Contributions are welcome! Please ensure:
- All new features include comprehensive docstrings
- Test coverage for new functionality
- Examples in documentation
- Error handling for edge cases
This project is licensed under the MIT License - see the LICENSE file for details.
For support, please contact:
- Email: [email protected], [email protected]
- Company: AR USA LLC
JSONPath-NZ (NextZen) - Powerful JSON manipulation with intelligent path handling