Beispiel #1
0
 private static void ComposeFilter(Filter node, StringBuilder expr) {
     ComposeExpression(node.Input, expr);
     expr.Append(s_LBracket);
     ComposeExpression(node.Condition, expr);
     expr.Append(s_RBracket);
 }
Beispiel #2
0
        //>> StepPattern    ::=    ChildOrAttributeAxisSpecifier NodeTest Predicate*   
        //>> ChildOrAttributeAxisSpecifier    ::=    @ ? | ('child' | 'attribute') '::' 
        private AstNode ParseStepPattern(AstNode qyInput) {
            AstNode  opnd;
            Axis.AxisType axisType = Axis.AxisType.Child;
            switch (this.scanner.Kind) {
            case XPathScanner.LexKind.At:                               //>> '@'
                axisType = Axis.AxisType.Attribute;
                NextLex();
                break;
            case XPathScanner.LexKind.Axe:                              //>> AxisName '::'
                axisType = GetAxis(this.scanner);
                if (axisType != Axis.AxisType.Child && axisType != Axis.AxisType.Attribute) {
                    throw new XPathException(Res.Xp_InvalidToken, scanner.SourceText);
                }
                NextLex();
                break;
            }
            XPathNodeType nodeType = (
                axisType == Axis.AxisType.Attribute ? XPathNodeType.Attribute :
                /* default: */                        XPathNodeType.Element
            );

            opnd = ParseNodeTest(qyInput, axisType, nodeType);

            while (XPathScanner.LexKind.LBracket == this.scanner.Kind) {
                opnd = new Filter(opnd, ParsePredicate(opnd));
            } 
            return opnd;
        }
Beispiel #3
0
 //>> FilterExpr ::= PrimaryExpr | FilterExpr Predicate 
 private AstNode ParseFilterExpr(AstNode  qyInput) {
     AstNode  opnd = ParsePrimaryExpr(qyInput);  
     while (this.scanner.Kind == XPathScanner.LexKind.LBracket) {
         // opnd must be a query
         opnd = new Filter(opnd, ParsePredicate(opnd));
     }
     return opnd;
 }
Beispiel #4
0
        //>> Step ::= '.' | '..' | ( AxisName '::' | '@' )? NodeTest Predicate*
        private AstNode ParseStep(AstNode  qyInput) {
            AstNode  opnd;
            if (XPathScanner.LexKind.Dot == this.scanner.Kind) {         //>> '.'
                NextLex();
                opnd = new Axis(Axis.AxisType.Self, qyInput);
            }
            else if (XPathScanner.LexKind.DotDot == this.scanner.Kind) { //>> '..'
                NextLex();
                opnd = new Axis(Axis.AxisType.Parent, qyInput);
            }
            else {                                                          //>> ( AxisName '::' | '@' )? NodeTest Predicate*
                Axis.AxisType axisType = Axis.AxisType.Child;
                switch (this.scanner.Kind) {
                case XPathScanner.LexKind.At:                               //>> '@'
                    axisType = Axis.AxisType.Attribute;
                    NextLex();
                    break;
                case XPathScanner.LexKind.Axe:                              //>> AxisName '::'
                    axisType = GetAxis(this.scanner);
                    NextLex();
                    break;
                }
                XPathNodeType nodeType = (
                    axisType == Axis.AxisType.Attribute ? XPathNodeType.Attribute :
//                    axisType == Axis.AxisType.Namespace ? XPathNodeType.Namespace : // No Idea why it's this way but othervise Axes doesn't work
                    /* default: */                        XPathNodeType.Element
                );

                opnd = ParseNodeTest(qyInput, axisType, nodeType);

                while (XPathScanner.LexKind.LBracket == this.scanner.Kind) {
                    opnd = new Filter(opnd, ParsePredicate(opnd));
                } 
            }
            return opnd;
        }
Beispiel #5
0
        /*
        private bool SplitQuery(BaseAxisQuery origQuery, BaseAxisQuery parent, BaseAxisQuery input) {
            parent = origQuery as BaseAxisQuery;
            if (parent == null || parent is GroupQuery || parent is PositionQuery || parent is OrQuery) {
                return false;
            }
            input = parent = (BaseAxisQuery)parent.Clone();
            parent = (BaseAxisQuery) parent.m_qyInput;
            while (parent != null && !parent.IsAxis) {
                parent = (BaseAxisQuery)parent.m_qyInput;
            }
            if (parent == null) {
                return false;
            }
            BaseAxisQuery temp = (BaseAxisQuery)parent.m_qyInput;
            if (temp == null) {
                return false;
            }
            parent.m_qyInput = null;
            parent = temp;
            return true;
        }
        */
        private IQuery ProcessFilter(Filter root, ref bool cache, ref bool position) {
            bool _cache = false;
            bool merge = false;
            bool _position = false;
            _specialAxis = false;
            bool filterflag = true;
            bool first = (filterCount == 0);

            IQuery opnd = ProcessNode(root.Condition, null, Regular_D, 
            Axis.AxisType.None, ref _cache, ref _position);

            filterCount++;
            if (root.Condition.ReturnType == XPathResultType.Error ) {
                _position = true;
            }
            if (root.Condition.ReturnType == XPathResultType.Number || 
                _cache || _position ) {
                hasPosition = true;
                filterflag = false;
                _smart = 0;
            }
            IQuery qyInput = ProcessNode(root.Input, null, Regular_D, 
            Axis.AxisType.None, ref cache, ref position );            

            if (hasPosition && qyInput is CacheQuery) {
                qyInput = ((CacheQuery)qyInput).m_qyInput;
            }
            if (firstInput == null) {
                firstInput =  qyInput as BaseAxisQuery;
            }
            _smart = 2;
            merge = qyInput.Merge;
            if (_cache || _position) {
                hasPosition = true;
                if (hasReverseAxis) {
                    if (merge) {
                        qyInput = new ReversePositionQuery(qyInput);                
                    }
                    else if (_cache) {
                        qyInput = new ForwardPositionQuery(qyInput); 
                    }
                }
                else {
                    if (_cache) {
                        qyInput = new ForwardPositionQuery(qyInput); 

                    }
                }
            }
            else if (root.Condition.ReturnType == XPathResultType.Number ) {
                hasPosition = true;
                if (hasReverseAxis && merge) {
                    qyInput = new ReversePositionQuery(qyInput);                

                }
            }
            if (first && firstInput != null) {
                if (merge && hasPosition) {
                    qyInput = new FilterQuery(qyInput, opnd);
                    IQuery parent = firstInput.m_qyInput;
                    if (parent == null || !firstInput.Merge) {
                        firstInput = null;
                        return qyInput;
                    }
                    IQuery input = qyInput;
                    qyInput = qyInput.Clone();
                    firstInput.m_qyInput = null;
                    firstInput = null;
                    return new MergeFilterQuery(parent, input);
                }
                firstInput = null;
            }
            return new FilterQuery(qyInput, opnd, filterflag);
        }