From 637b8b68501dc65fd83a1094fa40dc06d386d8d6 Mon Sep 17 00:00:00 2001 From: Jeff Davis <14242442+JefeDavis@users.noreply.github.com> Date: Fri, 28 May 2021 15:31:08 -0500 Subject: [PATCH] feat: allow filters to work on all nodes (#49) filter expressions can now be used on all nodes not just arrays Closes #48 Signed-off-by: Jeff Davis --- README.md | 95 ++++++++++++++++++++++---------------------- pkg/yamlpath/path.go | 4 -- 2 files changed, 47 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 5c4e36d..83255d5 100644 --- a/README.md +++ b/README.md @@ -11,71 +11,70 @@ Valid paths are strings conforming to the following BNF syntax. ``` ::= | | | - ; an undotted child is allowed at the start of a path - ::= "" ; the current node - ::= "$" ; the root node of a document + | ; an undotted child is allowed at the start of a path + ::= "" ; the current node + ::= "$" ; the root node of a document ::= | | | ::= | - ::= "." | ".*" ; named child (restricted characters) or all children - ::= "[" "]" | "[" "]~" ; named children | property names of children + ::= "." | ".*" ; named child (restricted characters) or all children + ::= "[" "]" | "[" "]~" ; named children | property names of children ::= | "," - ::= | ; named child (restricted characters) - | ; array access of named child - "~" ; property name of child - "*" ; all children - "*" ; array access of all children + ::= | ; named child (restricted characters) + | ; array access of named child + "~" ; property name of child + "*" ; all children + "*" ; array access of all children ::= "'" "'" | '"' '"' - ::= "\'" | ; escaped single quote - "\\" | ; escaped backslash + ::= "\'" | ; escaped single quote + "\\" | ; escaped backslash | - "" ; empty string - ::= '\"' | ; escaped double quote - '\\' | ; escaped backslash + "" ; empty string + ::= '\"' | ; escaped double quote + '\\' | ; escaped backslash | - "" ; empty string + "" ; empty string - ::= ".." | ; all the descendants named - ".." ; array access of all descendents - - ::= "[" union "]" | "[" "]" ; zero or more elements of a sequence + ::= ".." | ; all the descendants named + ".." | ; array access of all descendents + ::= "[" union "]" | "[" "]" ; zero or more elements of a sequence ::= | "," - ::= | | "*" ; specific index, range of indices, or all indices - ::= ":" | ; start (inclusive) to end (exclusive) - ":" ":" ; start (inclusive) to end (exclusive) by step + ::= | | "*" ; specific index, range of indices, or all indices + ::= ":" | ; start (inclusive) to end (exclusive) + ":" ":" ; start (inclusive) to end (exclusive) by step ::= "?(" ")" ::= | - "||" ; disjunction + "||" ; disjunction ::= | - "&&" ; conjunction (binds more tightly than ||) - ::= | ; subpath exists - "!" | ; negation - "==" | ; equality - "!=" | ; inequality - ">" | ; numeric greater than - ">=" | ; numeric greater than or equal to - "<" | ; numeric less than - "<=" | ; numeric less than or equal to - "=~" |; subpath value matches regular expression - "(" ")" ; bracketing - ::= "@" | ; item relative to element being processed - "@" | ; value of element being processed - "$" | ; item relative to root node of a document + "&&" ; conjunction (binds more tightly than ||) + ::= | ; subpath exists + "!" | ; negation + "==" | ; equality + "!=" | ; inequality + ">" | ; numeric greater than + ">=" | ; numeric greater than or equal to + "<" | ; numeric less than + "<=" | ; numeric less than or equal to + "=~" | ; subpath value matches regular expression + "(" ")" ; bracketing + ::= "@" | ; item relative to element being processed + "@" | ; value of element being processed + "$" | ; item relative to root node of a document - ::= "@" | ; item, relative to element being processed - "$" ; item, relative to root node of a document - ::= | ; positive or negative decimal integer - | ; floating point number - "'" "'" | ; string enclosed in single quotes - "true" | "false" | ; boolean (must not be quoted) - "null" ; null (must not be quoted) - ::= "/" "/" ; Go regular expression with any "/" in the regex escaped as "\/" + ::= "@" | ; item, relative to element being processed + "$" ; item, relative to root node of a document + ::= | ; positive or negative decimal integer + | ; floating point number + "'" "'" | ; string enclosed in single quotes + "true" | "false" | ; boolean (must not be quoted) + "null" ; null (must not be quoted) + ::= "/" "/" ; Go regular expression with any "/" in the regex escaped as "\/" ``` The `NewPath` function parses a string path and returns a corresponding value of the `Path` type and @@ -136,9 +135,9 @@ A matcher of the form `[*]` selects all the nodes in each sequence node. ### Filters: `[?()]` -This matches selects a subsequence of each sequence node in the input slice satisfying the filter expression. +This matcher selects a subset of each node in the input satisfying the filter expression. -Filter expression are composed of three kinds of term: +Filter expressions are composed of three kinds of term: * `@` terms which produce a slice of descendants of the current node being matched (which is a node in one of the input sequences). Any path expression may be appended after the `@` to determine which descendants to include. * `$` terms which produce a slice of descendants of the root node. Any path expression may be appended after the `$` to determine which descendants to include. * Integer, floating point, and string literals (enclosed in single quotes, e.g. 'x'). diff --git a/pkg/yamlpath/path.go b/pkg/yamlpath/path.go index 29e5a59..f5072b8 100644 --- a/pkg/yamlpath/path.go +++ b/pkg/yamlpath/path.go @@ -426,10 +426,6 @@ func arraySubscriptThen(subscript string, p *Path) *Path { func filterThen(filterLexemes []lexeme, p *Path) *Path { filter := newFilter(newFilterNode(filterLexemes)) return new(func(node, root *yaml.Node) yit.Iterator { - if node.Kind != yaml.SequenceNode { - return empty(node, root) - } - its := []yit.Iterator{} for _, c := range node.Content { if filter(c, root) {