private Selector(string query, Element root) { if (query == null) { throw new ArgumentNullException("query"); } query = query.Trim(); if (string.IsNullOrEmpty(query)) { throw new ArgumentNullException("query"); } if (root == null) { throw new ArgumentNullException("root"); } this._evaluator = QueryParser.Parse(query); this._root = root; }
public Parent(Evaluator evaluator) { this._evaluator = evaluator; }
public Not(Evaluator evaluator) { this._evaluator = evaluator; }
public Has(Evaluator evaluator) { this._evaluator = evaluator; }
public ImmediatePreviousSibling(Evaluator evaluator) { this._evaluator = evaluator; }
public PreviousSibling(Evaluator evaluator) { this._evaluator = evaluator; }
public ImmediateParent(Evaluator evaluator) { this._evaluator = evaluator; }
private void Combinator(char combinator) { _tq.ConsumeWhitespace(); string subQuery = ConsumeSubQuery(); // support multi > childs Evaluator rootEval; // the new topmost evaluator Evaluator currentEval; // the evaluator the new eval will be combined to. could be root, or rightmost or. Evaluator newEval = Parse(subQuery); // the evaluator to add into target evaluator bool replaceRightMost = false; if (_evals.Count == 1) { rootEval = currentEval = _evals[0]; // make sure OR (,) has precedence: if (rootEval is CombiningEvaluator.Or && combinator != ',') { currentEval = ((CombiningEvaluator.Or)currentEval).RightMostEvaluator(); replaceRightMost = true; } } else { rootEval = currentEval = new CombiningEvaluator.And(_evals); } _evals.Clear(); Evaluator f = Parse(subQuery); // for most combinators: change the current eval into an AND of the current eval and the new eval if (combinator == '>') { currentEval = new CombiningEvaluator.And(newEval, new StructuralEvaluator.ImmediateParent(currentEval)); } else if (combinator == ' ') { currentEval = new CombiningEvaluator.And(newEval, new StructuralEvaluator.Parent(currentEval)); } else if (combinator == '+') { currentEval = new CombiningEvaluator.And(newEval, new StructuralEvaluator.ImmediatePreviousSibling(currentEval)); } else if (combinator == '~') { currentEval = new CombiningEvaluator.And(newEval, new StructuralEvaluator.PreviousSibling(currentEval)); } else if (combinator == ',') { // group or. CombiningEvaluator.Or or; if (currentEval is CombiningEvaluator.Or) { or = (CombiningEvaluator.Or)currentEval; or.Add(newEval); } else { or = new CombiningEvaluator.Or(); or.Add(currentEval); or.Add(newEval); } currentEval = or; } else { throw new Selector.SelectorParseException("Unknown combinator: " + combinator); } if (replaceRightMost) { ((CombiningEvaluator.Or)rootEval).ReplaceRightMostEvaluator(currentEval); } else { rootEval = currentEval; } _evals.Add(rootEval); }
public void Add(Evaluator e) { _evaluators.Add(e); }
public void ReplaceRightMostEvaluator(Evaluator replacement) { _evaluators[_evaluators.Count - 1] = replacement; }
public Accumulator(Element root, Elements elements, Evaluator eval) { this.root = root; this.elements = elements; this.eval = eval; }
/// <summary> /// Build a list of elements, by visiting root and every descendant of root, and testing it against the evaluator. /// </summary> /// <param name="eval">Evaluator to test elements against</param> /// <param name="root">root of tree to descend</param> /// <returns>list of matches; empty if none</returns> public static Elements Collect(Evaluator eval, Element root) { Elements elements = new Elements(); new NodeTraversor(new Accumulator(root, elements, eval)).Traverse(root); return elements; }