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); }
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); }
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); }
private AttributeQuery(AttributeQuery other) : base(other) { this.onAttribute = other.onAttribute; }
private AttributeQuery(AttributeQuery other) : base(other) { _onAttribute = other._onAttribute; }
private AttributeQuery(AttributeQuery other) : base((BaseAxisQuery)other) { this.onAttribute = other.onAttribute; }