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
```
## 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
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("split", splitStringOpType),
simpleOp("parents", getParentsOpType),
{"ParentWithLevel", `parent\([0-9]+\)`, parentWithLevel(), 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 isKeyOpType = &operationType{Type: "IS_KEY", NumArgs: 0, Precedence: 50, Handler: isKeyOperator}
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 getAnchorOpType = &operationType{Type: "GET_ANCHOR", NumArgs: 0, Precedence: 50, Handler: getAnchorOperator}

View File

@ -6,6 +6,26 @@ type parentOpPreferences struct {
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) {
log.Debugf("getParentOperator")

View File

@ -29,6 +29,15 @@ var parentOperatorScenarios = []expressionScenario{
"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",
subdescription: "You can optionally supply the number of levels to go up for the parent, the default being 1.",