Browse Source

Support 'OR' and 'AND' on Filter

pull/56/head
Kalle Stenflo 10 years ago
parent
commit
13a0bb2ef1
  1. 9
      README.md
  2. 31
      json-path/src/main/java/com/jayway/jsonpath/Filter.java
  3. 25
      json-path/src/test/java/com/jayway/jsonpath/FilterTest.java
  4. 3
      json-path/src/test/java/com/jayway/jsonpath/PredicateTest.java

9
README.md

@ -193,7 +193,8 @@ Inline predicates are the ones defined in the path.
List<Map<String, Object>> books = JsonPath.parse(json).read("$.store.book[?(@.price < 10)]");
```
In the current implementation you can use `&&` to combine multiple predicates `[?(@.price < 10 && @.category == 'fiction')]`. OR operations are not supported yet.
In the current implementation you can use `&&` to combine multiple predicates `[?(@.price < 10 && @.category == 'fiction')]`.
OR operations are not supported in inline predicates yet.
###The Filter API
@ -214,6 +215,12 @@ List<Map<String, Object>> books = parse(json).read("$.store.book[?]", cheapFict
Notice the placeholder `?` for the filter in the path. When multiple filters are provided they are applied in order where the number of placeholders must match
the number of provided filters. You can specify multiple predicate placeholders in one filter operation `[?, ?]`, both predicates must match.
Filters can also be combined with 'OR' and 'AND'
```java
Filter fooOrBar = filter(where("foo").exists(true)).or(where("bar").exists(true));
Filter fooAndBar = filter(where("foo").exists(true)).and(where("bar").exists(true));
```
###Roll Your Own
Third option is to implement your own predicates

31
json-path/src/main/java/com/jayway/jsonpath/Filter.java

@ -3,12 +3,17 @@ package com.jayway.jsonpath;
import java.util.ArrayList;
import java.util.List;
import static java.util.Arrays.asList;
/**
*
*/
public class Filter implements Predicate {
private List<Predicate> criteriaList = new ArrayList<Predicate>();
protected List<Predicate> criteriaList = new ArrayList<Predicate>();
private Filter() {
}
private Filter(Predicate criteria) {
this.criteriaList.add(criteria);
@ -18,6 +23,8 @@ public class Filter implements Predicate {
this.criteriaList = criteriaList;
}
/**
* Creates a new Filter based on given criteria
* @param criteria criteria
@ -54,4 +61,26 @@ public class Filter implements Predicate {
}
return sb.toString();
}
public Filter or(final Predicate other){
return new Filter(){
@Override
public boolean apply(PredicateContext ctx) {
boolean a = Filter.this.apply(ctx);
boolean b = other.apply(ctx);
return a || b;
}
};
}
public Filter and(final Predicate other){
return new Filter(){
@Override
public boolean apply(PredicateContext ctx) {
boolean a = Filter.this.apply(ctx);
boolean b = other.apply(ctx);
return a && b;
}
};
}
}

25
json-path/src/test/java/com/jayway/jsonpath/FilterTest.java

@ -2,6 +2,7 @@ package com.jayway.jsonpath;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
@ -385,4 +386,28 @@ public class FilterTest extends BaseTest {
};
assertThat(filter(where("string-key").eq("string").and("$").matches(p)).apply(createPredicateContext(json))).isEqualTo(true);
}
//----------------------------------------------------------------------------
//
// OR
//
//----------------------------------------------------------------------------
@Test
public void or_and_filters_evaluates() {
Map<String, Object> model = new HashMap<String, Object>();
model.put("foo", true);
model.put("bar", false);
Filter isFoo = filter(where("foo").is(true));
Filter isBar = filter(where("bar").is(true));
Filter fooOrBar = filter(where("foo").exists(true)).or(where("bar").exists(true));
Filter fooAndBar = filter(where("foo").exists(true)).and(where("bar").exists(true));
assertThat(isFoo.or(isBar).apply(createPredicateContext(model))).isTrue();
assertThat(isFoo.and(isBar).apply(createPredicateContext(model))).isFalse();
}
}

3
json-path/src/test/java/com/jayway/jsonpath/PredicateTest.java

@ -14,7 +14,6 @@ public class PredicateTest extends BaseTest {
@Test
public void predicates_filters_can_be_applied() {
Predicate booksWithISBN = new Predicate() {
@Override
public boolean apply(PredicateContext ctx) {
@ -23,7 +22,5 @@ public class PredicateTest extends BaseTest {
};
assertThat(reader.read("$.store.book[?].isbn", List.class, booksWithISBN)).containsOnly("0-395-19395-8", "0-553-21311-3");
}
}

Loading…
Cancel
Save