func (b *builder) processFilterNode(root *filterNode) (query, error) {
	b.flag |= filterFlag
	qyInput, err := b.processNode(root.Input)
	if err != nil {
		return nil, err
	}
	qyCond, err := b.processNode(root.Condition)
	if err != nil {
		return nil, err
	}
	qyOutput := &filterQuery{Input: qyInput, Predicate: qyCond}
	return qyOutput, nil
}
processFilterNode builds query for the XPath filter predicate.
package xpath
import (
	"errors"
	"fmt"
)
type flag int
const (
	noneFlag flag = iota
	filterFlag
)
type builder struct {
	depth      int
	flag       flag
	firstInput query
}
func axisPredicate(root *axisNode) func(NodeNavigator) bool {
	typ := ElementNode
	switch root.AxeType {
	case "attribute":
		typ = AttributeNode
	case "self", "parent":
		typ = allNode
	default:
		switch root.Prop {
		case "comment":
			typ = CommentNode
		case "text":
			typ = TextNode
		case "node":
			typ = allNode
		}
	}
	nametest := root.LocalName != "" || root.Prefix != ""
	predicate := func(n NodeNavigator) bool {
		if typ == n.NodeType() || typ == allNode || typ == TextNode {
			if nametest {
				if root.LocalName == n.LocalName() && root.Prefix == n.Prefix() {
					return true
				}
			} else {
				return true
			}
		}
		return false
	}
	return predicate
}
func (b *builder) processAxisNode(root *axisNode) (query, error) {
	var (
		err       error
		qyInput   query
		qyOutput  query
		predicate = axisPredicate(root)
	)
	if root.Input == nil {
		qyInput = &contextQuery{}
	} else {
		if root.AxeType == "child" && (root.Input.Type() == nodeAxis) {
			if input := root.Input.(*axisNode); input.AxeType == "descendant-or-self" {
				var qyGrandInput query
				if input.Input != nil {
					qyGrandInput, _ = b.processNode(input.Input)
				} else {
					qyGrandInput = &contextQuery{}
				}
				filter := func(n NodeNavigator) bool {
					v := predicate(n)
					switch root.Prop {
					case "text":
						v = v && n.NodeType() == TextNode
					case "comment":
						v = v && n.NodeType() == CommentNode
					}
					return v
				}
				qyOutput = &descendantQuery{Input: qyGrandInput, Predicate: filter, Self: true}
				return qyOutput, nil
			}
		}
		qyInput, err = b.processNode(root.Input)
		if err != nil {
			return nil, err
		}
	}
	switch root.AxeType {
	case "ancestor":
		qyOutput = &ancestorQuery{Input: qyInput, Predicate: predicate}
	case "ancestor-or-self":
		qyOutput = &ancestorQuery{Input: qyInput, Predicate: predicate, Self: true}
	case "attribute":
		qyOutput = &attributeQuery{Input: qyInput, Predicate: predicate}
	case "child":
		filter := func(n NodeNavigator) bool {
			v := predicate(n)
			switch root.Prop {
			case "text":
				v = v && n.NodeType() == TextNode
			case "node":
				v = v && (n.NodeType() == ElementNode || n.NodeType() == TextNode)
			case "comment":
				v = v && n.NodeType() == CommentNode
			}
			return v
		}
		qyOutput = &childQuery{Input: qyInput, Predicate: filter}
	case "descendant":
		qyOutput = &descendantQuery{Input: qyInput, Predicate: predicate}
	case "descendant-or-self":
		qyOutput = &descendantQuery{Input: qyInput, Predicate: predicate, Self: true}
	case "following":
		qyOutput = &followingQuery{Input: qyInput, Predicate: predicate}
	case "following-sibling":
		qyOutput = &followingQuery{Input: qyInput, Predicate: predicate, Sibling: true}
	case "parent":
		qyOutput = &parentQuery{Input: qyInput, Predicate: predicate}
	case "preceding":
		qyOutput = &precedingQuery{Input: qyInput, Predicate: predicate}
	case "preceding-sibling":
		qyOutput = &precedingQuery{Input: qyInput, Predicate: predicate, Sibling: true}
	case "self":
		qyOutput = &selfQuery{Input: qyInput, Predicate: predicate}
	case "namespace":
	default:
		err = fmt.Errorf("unknown axe type: %s", root.AxeType)
		return nil, err
	}
	return qyOutput, nil
}