A complete Go implementation of JSONPath that fully complies with RFC 9535. Provides both a command-line tool and a Go library with support for all standard JSONPath features.
- Complete RFC 9535 Implementation
- Root node access (
$) - Child node access (
.keyor['key']) - Recursive descent (
..) - Array indices (
[0],[-1]) - Array slices (
[start:end:step]) - Array wildcards (
[*]) - Multiple indices (
[1,2,3]) - Multiple field names (
['name','age']) - Filter expressions (
[?(@.price < 10)]) 
 - Root node access (
 - Command Line Tool (
jp)- Beautiful colorized output
 - Syntax highlighting for JSON
 - File and stdin input support
 - Formatted and compact output options
 - User-friendly error messages
 - UTF-8 support with proper CJK display
 
 - Go Library
- Clean API design
 - Type-safe operations
 - Rich examples
 - Comprehensive documentation
 
 
- Bug fixes and improvements
- Fixed minor issues from the initial 2.0.0 release
 - Improved error handling and reporting
 - Performance optimizations
 
 - Documentation updates
- Updated examples to reflect latest API changes
 - Enhanced documentation clarity
 - Fixed typos and inconsistencies
 
 
- New Features
- Support for multiple field name extraction (
['name','age']) - Enhanced array indexing with mixed field types
 
 - Support for multiple field name extraction (
 - Improvements
- Better error handling for multi-field expressions
 - Performance optimizations for complex queries
 
 - Documentation
- Added examples for multi-field extraction
 - Updated feature list to include multi-field support
 
 
- Complete rewrite with RFC 9535 compliance
- Full implementation of JSONPath specification (RFC 9535)
 - Enhanced error handling and reporting
 - Improved performance and reliability
 - Better support for various JSONPath expressions
 
 - Breaking Changes
- API changes to align with RFC specification
 - Updated function signatures for better usability
 - Modified error types for more detailed error reporting
 
 - Documentation
- Updated documentation to reflect RFC compliance
 - Added more examples and use cases
 - Improved API documentation
 
 
- Centralize version management
- Add version.go for centralized version control
 - Update cmd/jp to use centralized version
 - Fix UTF-8 encoding in Chinese comments
 
 
- Enhanced filter expressions
- Full support for logical operators (
&&,||,!) - Proper handling of complex filter conditions
 - Support for De Morgan's Law in negated expressions
 - Improved numeric and string comparisons
 - Better error messages
 
 - Full support for logical operators (
 - Improved API design
- New simplified 
Queryfunction for easier usage - Deprecated 
Compile/Executein favor ofQuery - Better error handling and reporting
 
 - New simplified 
 - Updated examples
- New examples demonstrating logical operators
 - Updated code to use new 
Queryfunction - Fixed UTF-8 encoding issues in examples
 
 
- Enhanced filter expressions
- Full support for logical operators (
&&,||,!) - Proper handling of complex filter conditions
 - Support for De Morgan's Law in negated expressions
 - Improved numeric and string comparisons
 - Better error messages
 
 - Full support for logical operators (
 - Enhanced colorized output
- Beautiful syntax highlighting for JSON
 - Colorful command-line interface
 - Improved readability for nested structures
 
 - Better UTF-8 support
- Fixed CJK character display
 - Proper handling of multi-byte characters
 
 
- Initial stable release
- Basic JSONPath query support
 - Command-line tool implementation
 - Core filter expression support
 - Basic colorized output
 - Initial documentation
 - Basic error handling
 - UTF-8 support
 
 
# Add tap
brew tap davidhoo/tap
# Install jsonpath
brew install jsonpathgo install github.com/davidhoo/jsonpath/cmd/jp@latestDownload the appropriate binary for your platform from the releases page.
jp [-p <jsonpath_expression>] [-f <json_file>] [-c]Options:
-pJSONPath expression (if not specified, output entire JSON)-fJSON file path (reads from stdin if not specified)-cCompact output (no formatting)--no-colorDisable colored output-hShow help information-vShow version information
# Output entire JSON with syntax highlighting
jp -f data.json
# Query specific path
jp -f data.json -p '$.store.book[*].author'
# Filter with conditions
jp -f data.json -p '$.store.book[?(@.price > 10)]'
# Read from stdin
echo '{"name": "John"}' | jp -p '$.name'
# Compact output
jp -f data.json -cimport "github.com/davidhoo/jsonpath"
// Query JSON data
result, err := jsonpath.Query(data, "$.store.book[*].author")
if err != nil {
    log.Fatal(err)
}
// Handle result
authors, ok := result.([]interface{})
if !ok {
    log.Fatal("unexpected result type")
}package main
import (
    "encoding/json"
    "fmt"
    "log"
    "github.com/davidhoo/jsonpath"
)
func main() {
    // JSON data
    data := `{
        "store": {
            "book": [
                {
                    "category": "reference",
                    "author": "Nigel Rees",
                    "title": "Sayings of the Century",
                    "price": 8.95
                },
                {
                    "category": "fiction",
                    "author": "Evelyn Waugh",
                    "title": "Sword of Honour",
                    "price": 12.99
                }
            ]
        }
    }`
    // Parse JSON
    var v interface{}
    if err := json.Unmarshal([]byte(data), &v); err != nil {
        log.Fatal(err)
    }
    // Execute JSONPath query
    result, err := jsonpath.Query(v, "$.store.book[?(@.price < 10)].title")
    if err != nil {
        log.Fatal(err)
    }
    // Print result
    fmt.Printf("%v\n", result) // ["Sayings of the Century"]
}// Get all prices (recursive)
"$..price"
// Get books with specific price range
"$.store.book[?(@.price < 10)].title"
// Get all authors
"$.store.book[*].author"
// Get first book
"$.store.book[0]"
// Get last book
"$.store.book[-1]"
// Get first two books
"$.store.book[0:2]"
// Get books with price > 10 and category == fiction
"$.store.book[?(@.price > 10 && @.category == 'fiction')]"
// Get all non-reference books
"$.store.book[?(!(@.category == 'reference'))]"
// Get books with price > 10 or author containing 'Evelyn'
"$.store.book[?(@.price > 10 || @.author == 'Evelyn Waugh')]"
// Get length of book array
"$.store.book.length()"
// Get all keys of store object
"$.store.keys()"
// Get all values of store object
"$.store.values()"
// Get minimum book price
"$.store.book[*].price.min()"
// Get maximum book price
"$.store.book[*].price.max()"
// Get average book price
"$.store.book[*].price.avg()"
// Get total price of all books
"$.store.book[*].price.sum()"
// Count fiction books
"$.store.book[*].category.count('fiction')"
// Match book titles with regex pattern
"$.store.book[?@.title.match('^S.*')]"
// Search for books with titles starting with 'S'
"$.store.book[*].title.search('^S.*')"
// Extract multiple fields from objects
"$.store.book[*]['author','price']"
// Extract multiple fields with wildcard
"$.store.book[*]['title','category']"
// Chain multiple functions
"$.store.book[?@.price > 10].title.length()"
// Complex function chaining
"$.store.book[?@.price > $.store.book[*].price.avg()].title"
// Combine search and filter
"$.store.book[?@.title.match('^S.*') && @.price < 10].author"Handle results according to their type using type assertions:
// Single value result
if str, ok := result.(string); ok {
    // Handle string result
}
// Array result
if arr, ok := result.([]interface{}); ok {
    for _, item := range arr {
        // Handle each item
    }
}
// Object result
if obj, ok := result.(map[string]interface{}); ok {
    // Handle object
}- 
RFC 9535 Compliance
- Support for all standard operators
 - Standard-compliant syntax parsing
 - Standard result formatting
 
 - 
Filter Support
- Comparison operators: 
<,>,<=,>=,==,!= - Logical operators: 
&&,||,! - Support for complex filter conditions
 - Support for numeric and string comparisons
 - Proper handling of negated expressions using De Morgan's Law
 - Nested filter conditions with parentheses
 
 - Comparison operators: 
 - 
Result Handling
- Array operations return array results
 - Single value access returns original type
 - Type-safe result handling
 
 - 
Error Handling
- Detailed error messages
 - Syntax error reporting
 - Runtime error handling
 
 
Issues and Pull Requests are welcome!
MIT License
# Run all tests
go test -v ./...
# Run tests with coverage
go test -v -coverprofile=coverage.out ./...
# View coverage report in browser
go tool cover -html=coverage.out
# Run benchmarks
go test -bench=. -benchmem ./...The test suite is organized into several categories:
- Unit Tests: Testing individual functions and components
 - Integration Tests: Testing interactions between components
 - Benchmark Tests: Performance testing of critical paths
 - Example Tests: Documenting usage through examples
 
Current test coverage metrics:
- Overall Coverage: 90%+
 - Core Package: 90%+
 - Command Line Tool: 90%+
 
When contributing tests, please follow these guidelines:
- Use table-driven tests for similar test cases
 - Provide clear test case descriptions
 - Test both success and error cases
 - Include edge cases and boundary conditions
 - Use test suites for related functionality
 - Add benchmarks for performance-critical code
 
Example of a well-structured test:
func TestParseJSONPath(t *testing.T) {
    tests := []struct {
        name     string
        input    string
        expected interface{}
        wantErr  bool
    }{
        {
            name:     "simple path",
            input:    "$.store.book",
            expected: []string{"store", "book"},
            wantErr:  false,
        },
        // Add more test cases...
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result, err := ParseJSONPath(tt.input)
            if (err != nil) != tt.wantErr {
                t.Errorf("ParseJSONPath() error = %v, wantErr %v", err, tt.wantErr)
                return
            }
            if !reflect.DeepEqual(result, tt.expected) {
                t.Errorf("ParseJSONPath() = %v, want %v", result, tt.expected)
            }
        })
    }
}