Skip to content

Wenrh2004/jsonpath

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

jsonpath

A performant and feature-rich JSONPath implementation for Go. Backed by bytedance/sonic for JSON parsing, it provides a fluent Builder API and generic result handling, designed for a concise and efficient JSON query experience.

Features

  • Full JSONPath Support:
    • Path Selectors: .key, ['key']
    • Array Operations: Index [i] (supports negative indexing), Slice [start:end:step]
    • Wildcard: *
    • Recursive Descent: ..
    • Filters: [?(expr)], supporting logical operators (&&, ||, !) and comparison operators (==, !=, >, >=, <, <=, =~)
  • High Performance: Powered by sonic for underlying JSON marshaling and unmarshaling.
  • Chainable Builder: Offers a fluent API for constructing queries, allowing a mix of standard JSONPath strings and programmatic building.
  • Generics Support: Directly map results to Go types (ResultsT[T], IntoT[T]).
  • Optional Support: Integrated with bytedance/gg/goption for Optional-style return value handling.

Installation

go get github.com/Wenrh2004/jsonpath

Quick Start

1. Basic Usage (Compile & Eval)

The most common way is to compile the path and then execute the query:

package main

import (
	"fmt"
	"github.com/Wenrh2004/jsonpath"
)

func main() {
	jsonStr := `{"store": {"book": [{"title": "Sayings of the Century", "price": 8.95}, {"title": "Sword of Honour", "price": 12.99}]}}`
	
	// 1. Compile the path
	q, err := jsonpath.Compile("$.store.book[?(@.price < 10)].title")
	if err != nil {
		panic(err)
	}

	// 2. Execute query (EvalBytes or Eval)
	nodes, err := q.EvalBytes([]byte(jsonStr))
	if err != nil {
		panic(err)
	}

	// 3. Get results
	// nodes is []core.Node, containing Path and Value
	fmt.Println("Result:", nodes[0].Value) // Output: Sayings of the Century
    
    // Or use generic helper functions to convert results
    titles, _ := jsonpath.Results[string](nodes)
    fmt.Println("Titles:", titles)
}

2. Chainable Builder API

The Builder pattern allows you to build queries programmatically or continue querying on specific nodes, offering great flexibility.

package main

import (
	"fmt"
	"github.com/Wenrh2004/jsonpath"
)

func main() {
	data := []byte(`...`) // Your JSON data

	// Create Builder from raw bytes
	builder, _ := jsonpath.FromBytes(data)

	// Chain calls: Store -> Book -> Price >= 20 -> First -> Title
	title, err := jsonpath.IntoT[string](
		builder.Clone().
			Select("$.store.book[?(@.price >= 20)]"). // Filter using JSONPath string
			Index(0).                                 // Get the 0th element (supports chaining on result sets)
			Child("title"),                           // Get title field
	)
	if err != nil {
		panic(err)
	}
	fmt.Println("Expensive book:", title)
}

3. Optional Style API

If you prefer Optional-style error handling (like Rust/Java Optional), you can use methods like EvalBytesO:

// Returns goption.O[[]core.Node]
optNodes := jsonpath.EvalBytesO(q, data, false)

if optNodes.IsPresent() {
    nodes := optNodes.Unwrap()
    // ...
}

Syntax Support

Syntax Description Example
$ Root node $
.key Child node (dot) $.store.book
['key'] Child node (bracket) $['store']['book']
* Wildcard (all children) $.store.book[*].author
.. Recursive descent $..author
[i] Array index (supports negative) $.book[0], $.book[-1]
[s:e:step] Array slice $.book[0:2], $.book[::-1]
[?(expr)] Filter expression $.book[?(@.price < 10)]
@ Current node (in filter) @.price
length() Length function [?(length(@.title) > 10)]

Filter Operators

  • Comparison: ==, !=, >, >=, <, <=
  • Regex: =~ (e.g., [?(@.name =~ 'Harry.*')])
  • Logical: &&, ||, ! (e.g., [?(@.price < 10 && @.category == 'fiction')])

Package Layout

  • jsonpath: Root package, providing core API (Compile, Eval, FromBytes) and Builder entry points.
  • jsonpath/core: Core engine, containing Lexer, Parser, AST execution (Segment), and evaluation logic (Eval).
  • jsonpath/builder: Builder implementation, providing fluent operation methods.
  • jsonpath/optional.go: Provides Optional-style helper APIs.

License

This project is licensed under the MIT License.

About

A performant and feature-rich JSONPath implementation for Go. Backed by `bytedance/sonic` for JSON parsing, it provides a fluent Builder API and generic result handling, designed for a concise and efficient JSON query experience.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages