func matchPath()

in internal/s11n/match.go [40:106]


func matchPath(ch chan<- *yaml.Node, n *yaml.Node, path []string) {
	if n.Kind == yaml.DocumentNode {
		for _, doc := range n.Content {
			matchPath(ch, doc, path)
		}
		return
	}

	if len(path) == 0 {
		ch <- n
		return
	}

	head, tail := path[0], path[1:]
	query := make([]string, 0)

	// Deal with recursive descent
	if head == "**" {
		matchPath(ch, n, tail)

		if n.Kind == yaml.MappingNode {
			for i := 0; i < len(n.Content); i += 2 {
				matchPath(ch, n.Content[i+1], path)
			}
		} else if n.Kind == yaml.SequenceNode {
			for _, child := range n.Content {
				matchPath(ch, child, path)
			}
		}
	}

	// Parse out any query
	parts := strings.Split(head, "|")
	if len(parts) == 2 {
		head = parts[0]
		query = parts[1:]
	}

	if n.Kind == yaml.MappingNode {
		for i := 0; i < len(n.Content); i += 2 {
			key := n.Content[i]

			if head == "*" || key.Value == head {
				value := n.Content[i+1]
				if filter(value, query) {
					matchPath(ch, value, tail)
				}
			}
		}
	} else if n.Kind == yaml.SequenceNode {
		if head == "*" {
			for _, child := range n.Content {
				if filter(child, query) {
					matchPath(ch, child, tail)
				}
			}
		} else {
			i, err := strconv.Atoi(head)
			if err == nil && i < len(n.Content) {
				value := n.Content[i]
				if filter(value, query) {
					matchPath(ch, value, tail)
				}
			}
		}
	}
}