Go JSONPath

中文文档
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.
Features
- Complete RFC 9535 Implementation
- Root node access (
$
)
- Child node access (
.key
or ['key']
)
- Recursive descent (
..
)
- Array indices (
[0]
, [-1]
)
- Array slices (
[start:end:step]
)
- Array wildcards (
[*]
)
- Multiple indices (
[1,2,3]
)
- Filter expressions (
[?(@.price < 10)]
)
- 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
What's New in v1.0.3
- 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
- Improved API design
- New simplified
Query
function for easier usage
- Deprecated
Compile/Execute
in favor of Query
- Better error handling and reporting
- Updated examples
- New examples demonstrating logical operators
- Updated code to use new
Query
function
- Fixed UTF-8 encoding issues in examples
Installation
Homebrew (Recommended)
# Add tap
brew tap davidhoo/tap
# Install jsonpath
brew install jsonpath
Go Install
go install github.com/davidhoo/jsonpath/cmd/jp@latest
Manual Installation
Download the appropriate binary for your platform from the releases page.
Command Line Usage
CLI Basic Usage
jp [-p <jsonpath_expression>] [-f <json_file>] [-c]
Options:
-p
JSONPath expression (if not specified, output entire JSON)
-f
JSON file path (reads from stdin if not specified)
-c
Compact output (no formatting)
--no-color
Disable colored output
-h
Show help information
-v
Show version information
Examples
# 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 -c
Go Library Usage
Library Basic Usage
import "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")
}
Complete Example
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"]
}
Common Query Examples
// Get all prices (recursive)
"$..price"
// Get books within 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 all books with price > 10 and category == 'fiction'
"$.store.book[?(@.price > 10 && @.category == 'fiction')]"
// Get all books that are not reference books
"$.store.book[?(!(@.category == 'reference'))]"
// Get all books with price > 10 or author containing 'Evelyn'
"$.store.book[?(@.price > 10 || @.author == 'Evelyn Waugh')]"
Result Handling
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
}
Implementation Details
-
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
-
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
Contributing
Issues and Pull Requests are welcome!
License
MIT License