Inheritance: BaseAxisQuery
Exemplo n.º 1
0
        public override XPathNavigator MatchNode(XPathNavigator current)
        {
            XPathNavigator context;

            if (current == null)
            {
                return(null);
            }
            context = qyInput.MatchNode(current);

            if (context != null)
            {
                // In this switch we process some special case in wich we can calculate predicate faster then in generic case
                switch (_cond.StaticType)
                {
                case XPathResultType.Number:
                    OperandQuery operand = _cond as OperandQuery;
                    if (operand != null)
                    {
                        double        val           = (double)operand.val;
                        ChildrenQuery childrenQuery = qyInput as ChildrenQuery;
                        if (childrenQuery != null)
                        {     // foo[2], but not foo[expr][2]
                            XPathNavigator result = current.Clone();
                            result.MoveToParent();
                            int i = 0;
                            result.MoveToFirstChild();
                            do
                            {
                                if (childrenQuery.matches(result))
                                {
                                    i++;
                                    if (current.IsSamePosition(result))
                                    {
                                        return(val == i ? context : null);
                                    }
                                }
                            } while (result.MoveToNext());
                            return(null);
                        }
                        AttributeQuery attributeQuery = qyInput as AttributeQuery;
                        if (attributeQuery != null)
                        {    // @foo[3], but not @foo[expr][2]
                            XPathNavigator result = current.Clone();
                            result.MoveToParent();
                            int i = 0;
                            result.MoveToFirstAttribute();
                            do
                            {
                                if (attributeQuery.matches(result))
                                {
                                    i++;
                                    if (current.IsSamePosition(result))
                                    {
                                        return(val == i ? context : null);
                                    }
                                }
                            } while (result.MoveToNextAttribute());
                            return(null);
                        }
                    }
                    break;

                case XPathResultType.NodeSet:
                    _cond.Evaluate(new XPathSingletonIterator(current, /*moved:*/ true));
                    return((_cond.Advance() != null) ? context : null);

                case XPathResultType.Boolean:
                    if (_noPosition)
                    {
                        return(((bool)_cond.Evaluate(new XPathSingletonIterator(current, /*moved:*/ true))) ? context : null);
                    }
                    break;

                case XPathResultType.String:
                    if (_noPosition)
                    {
                        return((((string)_cond.Evaluate(new XPathSingletonIterator(current, /*moved:*/ true))).Length != 0) ? context : null);
                    }
                    break;

                case XPathResultType_Navigator:
                    return(context);

                default:
                    return(null);
                }
                /* Generic case */
                {
                    Evaluate(new XPathSingletonIterator(context, /*moved:*/ true));
                    XPathNavigator result;
                    while ((result = Advance()) != null)
                    {
                        if (result.IsSamePosition(current))
                        {
                            return(context);
                        }
                    }
                }
            }
            return(null);
        }
Exemplo n.º 2
0
        private Query ProcessAxis(Axis root, Flags flags, out Props props)
        {
            Query result = null;

            if (root.Prefix.Length > 0)
            {
                needContext = true;
            }
            firstInput = null;
            Query qyInput; {
                if (root.Input != null)
                {
                    Flags inputFlags = Flags.None;
                    if ((flags & Flags.PosFilter) == 0)
                    {
                        Axis input = root.Input as Axis;
                        if (input != null)
                        {
                            if (
                                root.TypeOfAxis == Axis.AxisType.Child &&
                                input.TypeOfAxis == Axis.AxisType.DescendantOrSelf && input.NodeType == XPathNodeType.All
                                )
                            {
                                Query qyGrandInput;
                                if (input.Input != null)
                                {
                                    qyGrandInput = ProcessNode(input.Input, Flags.SmartDesc, out props);
                                }
                                else
                                {
                                    qyGrandInput = new ContextQuery();
                                    props        = Props.None;
                                }
                                result = new DescendantQuery(qyGrandInput, root.Name, root.Prefix, root.NodeType, false, input.AbbrAxis);
                                if ((props & Props.NonFlat) != 0)
                                {
                                    result = new DocumentOrderQuery(result);
                                }
                                props |= Props.NonFlat;
                                return(result);
                            }
                        }
                        if (root.TypeOfAxis == Axis.AxisType.Descendant || root.TypeOfAxis == Axis.AxisType.DescendantOrSelf)
                        {
                            inputFlags |= Flags.SmartDesc;
                        }
                    }

                    qyInput = ProcessNode(root.Input, inputFlags, out props);
                }
                else
                {
                    qyInput = new ContextQuery();
                    props   = Props.None;
                }
            }

            switch (root.TypeOfAxis)
            {
            case Axis.AxisType.Ancestor:
                result = new XPathAncestorQuery(qyInput, root.Name, root.Prefix, root.NodeType, false);
                props |= Props.NonFlat;
                break;

            case Axis.AxisType.AncestorOrSelf:
                result = new XPathAncestorQuery(qyInput, root.Name, root.Prefix, root.NodeType, true);
                props |= Props.NonFlat;
                break;

            case Axis.AxisType.Child:
                if ((props & Props.NonFlat) != 0)
                {
                    result = new CacheChildrenQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                }
                else
                {
                    result = new ChildrenQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                }
                break;

            case Axis.AxisType.Parent:
                result = new ParentQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                break;

            case Axis.AxisType.Descendant:
                if ((flags & Flags.SmartDesc) != 0)
                {
                    result = new DescendantOverDescendantQuery(qyInput, false, root.Name, root.Prefix, root.NodeType, /*abbrAxis:*/ false);
                }
                else
                {
                    result = new DescendantQuery(qyInput, root.Name, root.Prefix, root.NodeType, false, /*abbrAxis:*/ false);
                    if ((props & Props.NonFlat) != 0)
                    {
                        result = new DocumentOrderQuery(result);
                    }
                }
                props |= Props.NonFlat;
                break;

            case Axis.AxisType.DescendantOrSelf:
                if ((flags & Flags.SmartDesc) != 0)
                {
                    result = new DescendantOverDescendantQuery(qyInput, true, root.Name, root.Prefix, root.NodeType, root.AbbrAxis);
                }
                else
                {
                    result = new DescendantQuery(qyInput, root.Name, root.Prefix, root.NodeType, true, root.AbbrAxis);
                    if ((props & Props.NonFlat) != 0)
                    {
                        result = new DocumentOrderQuery(result);
                    }
                }
                props |= Props.NonFlat;
                break;

            case Axis.AxisType.Preceding:
                result = new PrecedingQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                props |= Props.NonFlat;
                break;

            case Axis.AxisType.Following:
                result = new FollowingQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                props |= Props.NonFlat;
                break;

            case Axis.AxisType.FollowingSibling:
                result = new FollSiblingQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                if ((props & Props.NonFlat) != 0)
                {
                    result = new DocumentOrderQuery(result);
                }
                break;

            case Axis.AxisType.PrecedingSibling:
                result = new PreSiblingQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                break;

            case Axis.AxisType.Attribute:
                result = new AttributeQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                break;

            case Axis.AxisType.Self:
                result = new XPathSelfQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                break;

            case Axis.AxisType.Namespace:
                if ((root.NodeType == XPathNodeType.All || root.NodeType == XPathNodeType.Element || root.NodeType == XPathNodeType.Attribute) && root.Prefix.Length == 0)
                {
                    result = new NamespaceQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                }
                else
                {
                    result = new EmptyQuery();
                }
                break;

            default:
                throw XPathException.Create(Res.Xp_NotSupported, query);
            }

            return(result);
        }
Exemplo n.º 3
0
 protected ChildrenQuery(ChildrenQuery other) : base(other)
 {
     this.iterator = Clone(other.iterator);
 }
Exemplo n.º 4
0
        public override XPathNavigator MatchNode(XPathNavigator current)
        {
            XPathNavigator navigator;
            XPathNavigator navigator4;

            if (current != null)
            {
                navigator = base.qyInput.MatchNode(current);
                if (navigator == null)
                {
                    goto Label_01B9;
                }
                switch (this.cond.StaticType)
                {
                case XPathResultType.Number:
                {
                    OperandQuery cond = this.cond as OperandQuery;
                    if (cond != null)
                    {
                        double        val     = (double)cond.val;
                        ChildrenQuery qyInput = base.qyInput as ChildrenQuery;
                        if (qyInput != null)
                        {
                            XPathNavigator e = current.Clone();
                            e.MoveToParent();
                            int num2 = 0;
                            e.MoveToFirstChild();
                            do
                            {
                                if (qyInput.matches(e))
                                {
                                    num2++;
                                    if (current.IsSamePosition(e))
                                    {
                                        if (val != num2)
                                        {
                                            return(null);
                                        }
                                        return(navigator);
                                    }
                                }
                            }while (e.MoveToNext());
                            return(null);
                        }
                        AttributeQuery query3 = base.qyInput as AttributeQuery;
                        if (query3 != null)
                        {
                            XPathNavigator navigator3 = current.Clone();
                            navigator3.MoveToParent();
                            int num3 = 0;
                            navigator3.MoveToFirstAttribute();
                            do
                            {
                                if (query3.matches(navigator3))
                                {
                                    num3++;
                                    if (current.IsSamePosition(navigator3))
                                    {
                                        if (val != num3)
                                        {
                                            return(null);
                                        }
                                        return(navigator);
                                    }
                                }
                            }while (navigator3.MoveToNextAttribute());
                            return(null);
                        }
                    }
                    goto Label_0192;
                }

                case XPathResultType.String:
                    if (!this.noPosition)
                    {
                        goto Label_0192;
                    }
                    if (((string)this.cond.Evaluate(new XPathSingletonIterator(current, true))).Length != 0)
                    {
                        return(navigator);
                    }
                    return(null);

                case XPathResultType.Boolean:
                    if (!this.noPosition)
                    {
                        goto Label_0192;
                    }
                    if ((bool)this.cond.Evaluate(new XPathSingletonIterator(current, true)))
                    {
                        return(navigator);
                    }
                    return(null);

                case XPathResultType.NodeSet:
                    this.cond.Evaluate(new XPathSingletonIterator(current, true));
                    if (this.cond.Advance() != null)
                    {
                        return(navigator);
                    }
                    return(null);

                case ((XPathResultType)4):
                    return(navigator);
                }
            }
            return(null);

Label_0192:
            this.Evaluate(new XPathSingletonIterator(navigator, true));
            while ((navigator4 = this.Advance()) != null)
            {
                if (navigator4.IsSamePosition(current))
                {
                    return(navigator);
                }
            }
Label_01B9:
            return(null);
        }
Exemplo n.º 5
0
 protected ChildrenQuery(ChildrenQuery other) : base((BaseAxisQuery)other)
 {
     this.iterator = XPathEmptyIterator.Instance;
     this.iterator = Query.Clone(other.iterator);
 }