private QueryExpression ParseExpression() { QueryExpression rootExpression = null; CompositeExpression parentExpression = null; while (_currentIndex < _expression.Length) { EatWhitespace(); if (_expression[_currentIndex] != '@') throw new JsonException("Unexpected character while parsing path query: " + _expression[_currentIndex]); _currentIndex++; List<PathFilter> expressionPath = new List<PathFilter>(); if (ParsePath(expressionPath, _currentIndex, true)) throw new JsonException("Path ended with open query."); EatWhitespace(); EnsureLength("Path ended with open query."); QueryOperator op; object value = null; if (_expression[_currentIndex] == ')' || _expression[_currentIndex] == '|' || _expression[_currentIndex] == '&') { op = QueryOperator.Exists; } else { op = ParseOperator(); EatWhitespace(); EnsureLength("Path ended with open query."); value = ParseValue(); EatWhitespace(); EnsureLength("Path ended with open query."); } BooleanQueryExpression booleanExpression = new BooleanQueryExpression { Path = expressionPath, Operator = op, Value = (op != QueryOperator.Exists) ? new JValue(value) : null }; if (_expression[_currentIndex] == ')') { if (parentExpression != null) { parentExpression.Expressions.Add(booleanExpression); return rootExpression; } return booleanExpression; } if (_expression[_currentIndex] == '&' && Match("&&")) { if (parentExpression == null || parentExpression.Operator != QueryOperator.And) { CompositeExpression andExpression = new CompositeExpression { Operator = QueryOperator.And }; if (parentExpression != null) parentExpression.Expressions.Add(andExpression); parentExpression = andExpression; if (rootExpression == null) rootExpression = parentExpression; } parentExpression.Expressions.Add(booleanExpression); } if (_expression[_currentIndex] == '|' && Match("||")) { if (parentExpression == null || parentExpression.Operator != QueryOperator.Or) { CompositeExpression orExpression = new CompositeExpression { Operator = QueryOperator.Or }; if (parentExpression != null) parentExpression.Expressions.Add(orExpression); parentExpression = orExpression; if (rootExpression == null) rootExpression = parentExpression; } parentExpression.Expressions.Add(booleanExpression); } } throw new JsonException("Path ended with open query."); }
public void BooleanExpressionTest() { BooleanQueryExpression e1 = new BooleanQueryExpression { Operator = QueryOperator.LessThan, Value = new JValue(3), Path = new List<PathFilter> { new ArrayIndexFilter() } }; Assert.True(e1.IsMatch(new JArray(1, 2, 3, 4, 5))); Assert.True(e1.IsMatch(new JArray(2, 3, 4, 5))); Assert.False(e1.IsMatch(new JArray(3, 4, 5))); Assert.False(e1.IsMatch(new JArray(4, 5))); BooleanQueryExpression e2 = new BooleanQueryExpression { Operator = QueryOperator.LessThanOrEquals, Value = new JValue(3), Path = new List<PathFilter> { new ArrayIndexFilter() } }; Assert.True(e2.IsMatch(new JArray(1, 2, 3, 4, 5))); Assert.True(e2.IsMatch(new JArray(2, 3, 4, 5))); Assert.True(e2.IsMatch(new JArray(3, 4, 5))); Assert.False(e2.IsMatch(new JArray(4, 5))); }