Added parents operator

This commit is contained in:
Mike Farah 2025-09-09 20:27:11 +10:00
parent 02b28073bf
commit 78bc9baffd
5 changed files with 54 additions and 0 deletions

View File

@ -56,6 +56,29 @@ will output
sam sam
``` ```
## Get parents
Match all parents
Given a sample.yml file of:
```yaml
a:
b:
c: cat
```
then
```bash
yq '.a.b.c | parents' sample.yml
```
will output
```yaml
- c: cat
- b:
c: cat
- a:
b:
c: cat
```
## N-th parent ## N-th parent
You can optionally supply the number of levels to go up for the parent, the default being 1. You can optionally supply the number of levels to go up for the parent, the default being 1.

View File

@ -130,6 +130,7 @@ var participleYqRules = []*participleYqRule{
simpleOp("contains", containsOpType), simpleOp("contains", containsOpType),
simpleOp("split", splitStringOpType), simpleOp("split", splitStringOpType),
simpleOp("parents", getParentsOpType),
{"ParentWithLevel", `parent\([0-9]+\)`, parentWithLevel(), 0}, {"ParentWithLevel", `parent\([0-9]+\)`, parentWithLevel(), 0},
{"ParentWithDefaultLevel", `parent`, parentWithDefaultLevel(), 0}, {"ParentWithDefaultLevel", `parent`, parentWithDefaultLevel(), 0},

View File

@ -128,6 +128,7 @@ var getKindOpType = &operationType{Type: "GET_KIND", NumArgs: 0, Precedence: 50,
var getKeyOpType = &operationType{Type: "GET_KEY", NumArgs: 0, Precedence: 50, Handler: getKeyOperator} var getKeyOpType = &operationType{Type: "GET_KEY", NumArgs: 0, Precedence: 50, Handler: getKeyOperator}
var isKeyOpType = &operationType{Type: "IS_KEY", NumArgs: 0, Precedence: 50, Handler: isKeyOperator} var isKeyOpType = &operationType{Type: "IS_KEY", NumArgs: 0, Precedence: 50, Handler: isKeyOperator}
var getParentOpType = &operationType{Type: "GET_PARENT", NumArgs: 0, Precedence: 50, Handler: getParentOperator} var getParentOpType = &operationType{Type: "GET_PARENT", NumArgs: 0, Precedence: 50, Handler: getParentOperator}
var getParentsOpType = &operationType{Type: "GET_PARENTS", NumArgs: 0, Precedence: 50, Handler: getParentsOperator}
var getCommentOpType = &operationType{Type: "GET_COMMENT", NumArgs: 0, Precedence: 50, Handler: getCommentsOperator} var getCommentOpType = &operationType{Type: "GET_COMMENT", NumArgs: 0, Precedence: 50, Handler: getCommentsOperator}
var getAnchorOpType = &operationType{Type: "GET_ANCHOR", NumArgs: 0, Precedence: 50, Handler: getAnchorOperator} var getAnchorOpType = &operationType{Type: "GET_ANCHOR", NumArgs: 0, Precedence: 50, Handler: getAnchorOperator}

View File

@ -6,6 +6,26 @@ type parentOpPreferences struct {
Level int Level int
} }
func getParentsOperator(_ *dataTreeNavigator, context Context, _ *ExpressionNode) (Context, error) {
log.Debugf("getParentsOperator")
var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
parentsList := &CandidateNode{Kind: SequenceNode, Tag: "!!seq"}
parent := candidate.Parent
for parent != nil {
parentsList.AddChild(parent)
parent = parent.Parent
}
results.PushBack(parentsList)
}
return context.ChildContext(results), nil
}
func getParentOperator(_ *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) { func getParentOperator(_ *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
log.Debugf("getParentOperator") log.Debugf("getParentOperator")

View File

@ -29,6 +29,15 @@ var parentOperatorScenarios = []expressionScenario{
"D0, P[b name], (!!str)::sam\n", "D0, P[b name], (!!str)::sam\n",
}, },
}, },
{
description: "Get parents",
subdescription: "Match all parents",
document: "{a: {b: {c: cat} } }",
expression: `.a.b.c | parents`,
expected: []string{
"D0, P[], (!!seq)::- {c: cat}\n- {b: {c: cat}}\n- {a: {b: {c: cat}}}\n",
},
},
{ {
description: "N-th parent", description: "N-th parent",
subdescription: "You can optionally supply the number of levels to go up for the parent, the default being 1.", subdescription: "You can optionally supply the number of levels to go up for the parent, the default being 1.",