diff options
Diffstat (limited to 'jsonpath/selector.go')
| -rw-r--r-- | jsonpath/selector.go | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/jsonpath/selector.go b/jsonpath/selector.go new file mode 100644 index 0000000..71c3ed2 --- /dev/null +++ b/jsonpath/selector.go @@ -0,0 +1,55 @@ +package jsonpath + +import ( + "src.userspace.com.au/query/json" +) + +type Selector func(*json.Node) bool + +// MatchAll returns a slice of the nodes that match the selector, +// from n and its children. +func (s Selector) MatchAll(n *json.Node) []*json.Node { + return s.matchAllInto(n, nil) +} + +func (s Selector) matchAllInto(n *json.Node, storage []*json.Node) []*json.Node { + if s(n) { + storage = append(storage, n) + } + + for child := n.FirstChild; child != nil; child = child.NextSibling { + storage = s.matchAllInto(child, storage) + } + + return storage +} + +// Match returns true if the node matches the selector. +func (s Selector) Match(n *json.Node) bool { + return s(n) +} + +// MatchFirst returns the first node that matches s, from n and its children. +func (s Selector) MatchFirst(n *json.Node) *json.Node { + if s.Match(n) { + return n + } + + for c := n.FirstChild; c != nil; c = c.NextSibling { + m := s.MatchFirst(c) + if m != nil { + return m + } + } + return nil +} + +// Filter returns the nodes in nodes that match the selector. +func (s Selector) Filter(nodes []*json.Node) (result []*json.Node) { + for _, n := range nodes { + if s(n) { + result = append(result, n) + } + } + return result +} |
