Kalle Stenflo
10 years ago
57 changed files with 257 additions and 1972 deletions
@ -1,12 +1,12 @@
|
||||
package com.jayway.jsonpath.internal.spi.compiler; |
||||
package com.jayway.jsonpath.internal; |
||||
|
||||
import com.jayway.jsonpath.Configuration; |
||||
import com.jayway.jsonpath.spi.compiler.EvaluationContext; |
||||
import com.jayway.jsonpath.spi.compiler.Path; |
||||
import com.jayway.jsonpath.internal.compiler.EvaluationContextImpl; |
||||
import com.jayway.jsonpath.internal.compiler.PathToken; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
class CompiledPath implements Path { |
||||
public class CompiledPath implements Path { |
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(CompiledPath.class); |
||||
|
@ -1,4 +1,4 @@
|
||||
package com.jayway.jsonpath.spi.compiler; |
||||
package com.jayway.jsonpath.internal; |
||||
|
||||
import com.jayway.jsonpath.Configuration; |
||||
|
@ -1,4 +1,4 @@
|
||||
package com.jayway.jsonpath.spi.compiler; |
||||
package com.jayway.jsonpath.internal; |
||||
|
||||
import com.jayway.jsonpath.Configuration; |
||||
|
@ -1,181 +0,0 @@
|
||||
package com.jayway.jsonpath.internal; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
public class PathFormalizer extends Parser { |
||||
|
||||
private static final Fragment ROOT = new Fragment(Type.ROOT, "$"); |
||||
private static final Fragment SCAN = new Fragment(Type.SCAN, ".."); |
||||
|
||||
|
||||
StringBuilder formalized = new StringBuilder(); |
||||
|
||||
public PathFormalizer(String path) { |
||||
super(path); |
||||
} |
||||
|
||||
|
||||
//$.store.book[?(@.isbn)].isbn
|
||||
//$['store']['book'][?(@['isbn'])]['isbn']
|
||||
|
||||
public String formalize() { |
||||
TokenBuffer buffer = new TokenBuffer(); |
||||
do { |
||||
char current = next(); |
||||
|
||||
switch (current) { |
||||
case '$': |
||||
buffer.append("$").flush(); |
||||
break; |
||||
case '.': |
||||
if (!buffer.isEmpty()) { |
||||
buffer.flush(); |
||||
} |
||||
if (peekIs(Token.DOT)) { |
||||
next(); |
||||
buffer.append("..").flush(); |
||||
} |
||||
break; |
||||
case '[': |
||||
if (!buffer.isEmpty()) { |
||||
buffer.flush(); |
||||
} |
||||
break; |
||||
case ']': |
||||
if (!buffer.isEmpty()) { |
||||
buffer.flush(); |
||||
} |
||||
break; |
||||
case '?': |
||||
if (peekIs(Token.OPEN_PARENTHESIS)) { |
||||
buffer.append("?" + nextUntil(Token.CLOSE_BRACKET)); |
||||
buffer.flush(); |
||||
} |
||||
break; |
||||
default: |
||||
buffer.append(current); |
||||
break; |
||||
} |
||||
} while (hasNext()); |
||||
|
||||
if (!buffer.isEmpty()) { |
||||
buffer.flush(); |
||||
} |
||||
for (Fragment f : buffer.getFragments()) { |
||||
formalized.append(f.toString()); |
||||
} |
||||
return formalized.toString(); |
||||
|
||||
} |
||||
|
||||
private static class TokenBuffer { |
||||
|
||||
private List<Fragment> fragments = new ArrayList<Fragment>(); |
||||
private StringBuilder sb = new StringBuilder(); |
||||
|
||||
public TokenBuffer append(String s) { |
||||
sb.append(s); |
||||
return this; |
||||
} |
||||
|
||||
public TokenBuffer append(char c) { |
||||
sb.append(c); |
||||
return this; |
||||
} |
||||
|
||||
public void flush() { |
||||
fragments.add(new Fragment(Type.PROPERTY, sb.toString().trim())); |
||||
sb = new StringBuilder(); |
||||
} |
||||
|
||||
public boolean isEmpty() { |
||||
return sb.length() == 0; |
||||
} |
||||
|
||||
public List<Fragment> getFragments() { |
||||
return fragments; |
||||
} |
||||
} |
||||
|
||||
private Fragment createFragment(String data) { |
||||
if ("$".equals(data)) { |
||||
return ROOT; |
||||
} else if ("..".equals(data)) { |
||||
return SCAN; |
||||
} else if (isInts(data, true)) { |
||||
return new Fragment(Type.INDEX, new String(data)); |
||||
} else { |
||||
return new Fragment(Type.PROPERTY, new String(data)); |
||||
} |
||||
|
||||
} |
||||
|
||||
private static class Fragment { |
||||
|
||||
|
||||
private Type type; |
||||
private String frag; |
||||
|
||||
private Fragment(Type type, String frag) { |
||||
this.type = type; |
||||
this.frag = frag; |
||||
} |
||||
/* |
||||
//"[-1:]" sliceFrom
|
||||
//"[:1]" sliceTo
|
||||
//"[0:5]" sliceBetween
|
||||
//"[1]"
|
||||
//"[1,2,3]"
|
||||
//"[(@.length - 1)]"
|
||||
*/ |
||||
|
||||
private static Fragment create(String str) { |
||||
|
||||
boolean isProperty = str.startsWith("'") && str.endsWith("'"); |
||||
|
||||
if (isProperty) { |
||||
return new Fragment(Type.PROPERTY, new String(str.substring(1, str.length()-1))); |
||||
} else if ("$".equals(str)) { |
||||
return ROOT; |
||||
} else if ("..".equals(str)) { |
||||
return SCAN; |
||||
} else if ("*".equals(str)) { |
||||
return new Fragment(Type.INDEX, new String(str)); |
||||
} else if ("-1:".equals(str)) { |
||||
return new Fragment(Type.INDEX, new String(str)); |
||||
} else if (":1".equals(str)) { |
||||
return new Fragment(Type.INDEX, new String(str)); |
||||
} else if ("1:2".equals(str)) { |
||||
return new Fragment(Type.INDEX, new String(str)); |
||||
} else if ("1".equals(str)) { |
||||
return new Fragment(Type.INDEX, new String(str)); |
||||
} else if ("1,2,3".equals(str)) { |
||||
return new Fragment(Type.INDEX, new String(str)); |
||||
} else if ("(@.length() - 1)".equals(str)) { |
||||
return new Fragment(Type.INDEX, new String(str)); |
||||
} else if ("?(@.foo == 'bar')".equals(str)) { |
||||
return new Fragment(Type.INDEX, new String(str)); |
||||
} else if ("1,2,3".equals(str)) { |
||||
return new Fragment(Type.INDEX, new String(str)); |
||||
} else { |
||||
return new Fragment(Type.PROPERTY, new String(str)); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public String toString() { |
||||
return frag; |
||||
} |
||||
} |
||||
|
||||
private static enum Type { |
||||
ROOT, |
||||
SCAN, |
||||
PROPERTY, |
||||
INDEX |
||||
} |
||||
|
||||
|
||||
|
||||
} |
@ -1,4 +0,0 @@
|
||||
package com.jayway.jsonpath.spi.compiler; |
||||
|
||||
public interface PathCompiler { |
||||
} |
@ -0,0 +1,52 @@
|
||||
package com.jayway.jsonpath; |
||||
|
||||
public class BaseTest { |
||||
|
||||
public static final String JSON_DOCUMENT = "{\n" + |
||||
" \"string-property\" : \"string-value\", \n" + |
||||
" \"int-property\" : " + Integer.MAX_VALUE + ", \n" + |
||||
" \"long-property\" : " + Long.MAX_VALUE + ", \n" + |
||||
" \"boolean-property\" : true, \n" + |
||||
" \"null-property\" : null, \n" + |
||||
" \"store\" : {\n" + |
||||
" \"book\" : [\n" + |
||||
" {\n" + |
||||
" \"category\" : \"reference\",\n" + |
||||
" \"author\" : \"Nigel Rees\",\n" + |
||||
" \"title\" : \"Sayings of the Century\",\n" + |
||||
" \"display-price\" : 8.95\n" + |
||||
" },\n" + |
||||
" {\n" + |
||||
" \"category\" : \"fiction\",\n" + |
||||
" \"author\" : \"Evelyn Waugh\",\n" + |
||||
" \"title\" : \"Sword of Honour\",\n" + |
||||
" \"display-price\" : 12.99\n" + |
||||
" },\n" + |
||||
" {\n" + |
||||
" \"category\" : \"fiction\",\n" + |
||||
" \"author\" : \"Herman Melville\",\n" + |
||||
" \"title\" : \"Moby Dick\",\n" + |
||||
" \"isbn\" : \"0-553-21311-3\",\n" + |
||||
" \"display-price\" : 8.99\n" + |
||||
" },\n" + |
||||
" {\n" + |
||||
" \"category\" : \"fiction\",\n" + |
||||
" \"author\" : \"J. R. R. Tolkien\",\n" + |
||||
" \"title\" : \"The Lord of the Rings\",\n" + |
||||
" \"isbn\" : \"0-395-19395-8\",\n" + |
||||
" \"display-price\" : 22.99\n" + |
||||
" }\n" + |
||||
" ],\n" + |
||||
" \"bicycle\" : {\n" + |
||||
" \"foo\" : \"baz\",\n" + |
||||
" \"color\" : \"red\",\n" + |
||||
" \"display-price\" : 19.95,\n" + |
||||
" \"foo:bar\" : \"fooBar\",\n" + |
||||
" \"dot.notation\" : \"new\",\n" + |
||||
" \"dash-notation\" : \"dashes\"\n" + |
||||
" }\n" + |
||||
" },\n" + |
||||
" \"foo\" : \"bar\",\n" + |
||||
" \"@id\" : \"ID\"\n" + |
||||
"}"; |
||||
} |
@ -1,16 +0,0 @@
|
||||
package com.jayway.jsonpath; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
|
||||
public class CastTest { |
||||
|
||||
public static final String JSON = "{\"sessionID\":7242750700467747000}" ; |
||||
|
||||
@Test |
||||
public void result_can_be_cast_to_Long(){ |
||||
Long actual = JsonPath.read(JSON, "$.sessionID"); |
||||
Long expected = new Long("7242750700467747000"); |
||||
Assert.assertEquals(expected, actual); |
||||
} |
||||
} |
@ -1,229 +0,0 @@
|
||||
package com.jayway.jsonpath; |
||||
|
||||
import com.jayway.jsonpath.spi.json.JsonProvider; |
||||
import com.jayway.jsonpath.spi.json.JsonProviderFactory; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
public class ExpressionEvalTest { |
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ExpressionEvalTest.class); |
||||
|
||||
public static final String DOCUMENT= "{\n" + |
||||
" \"characters\": [\n" + |
||||
" {\n" + |
||||
" \"aliases\": [], \n" + |
||||
" \"name\": \"Kleeg Lars\", \n" + |
||||
" \"occupation\": \"Moisture farmer\", \n" + |
||||
" \"offspring\": []\n" + |
||||
" }, \n" + |
||||
" {\n" + |
||||
" \"aliases\": [], \n" + |
||||
" \"name\": \"Shmi Skywalker\", \n" + |
||||
" \"occupation\": \"Virgin mother\", \n" + |
||||
" \"offspring\": [\n" + |
||||
" \"AnakinSkywalker\"\n" + |
||||
" ]\n" + |
||||
" }, \n" + |
||||
" {\n" + |
||||
" \"aliases\": [\n" + |
||||
" \"Darth Vader\"\n" + |
||||
" ], \n" + |
||||
" \"name\": \"Annakin Skywalker\", \n" + |
||||
" \"occupation\": \"Hand of the Emperor, Lord of the Sith\", \n" + |
||||
" \"offspring\": [\n" + |
||||
" \"Luke Skywalker\", \n" + |
||||
" \"LeiaOrgana\"\n" + |
||||
" ]\n" + |
||||
" }, \n" + |
||||
" {\n" + |
||||
" \"aliases\": [\n" + |
||||
" \"Nerf herder\"\n" + |
||||
" ], \n" + |
||||
" \"name\": \"Luke Skywalker\", \n" + |
||||
" \"occupation\": \"Farm boy\", \n" + |
||||
" \"offspring\": null\n" + |
||||
" }, \n" + |
||||
" {\n" + |
||||
" \"aliases\": [\n" + |
||||
" \"Your Highness\"\n" + |
||||
" ], \n" + |
||||
" \"name\": \"Leia Organa\", \n" + |
||||
" \"occupation\": \"Senator\" \n" + |
||||
" }\n" + |
||||
" ]\n" + |
||||
"}\n"; |
||||
|
||||
private static final JsonProvider jp = JsonProviderFactory.createProvider(); |
||||
/* |
||||
@Test |
||||
public void long_eval() throws Exception { |
||||
|
||||
assertTrue(ExpressionEvaluator.eval(1L, "==", "1")); |
||||
assertTrue(ExpressionEvaluator.eval(2L, "!=", "1")); |
||||
assertTrue(ExpressionEvaluator.eval(2L, ">", "1")); |
||||
assertTrue(ExpressionEvaluator.eval(2L, ">=", "1")); |
||||
assertTrue(ExpressionEvaluator.eval(2L, ">=", "2")); |
||||
assertTrue(ExpressionEvaluator.eval(1L, "<", "2")); |
||||
assertTrue(ExpressionEvaluator.eval(2L, "<=", "2")); |
||||
|
||||
assertFalse(ExpressionEvaluator.eval(1, ">", "2")); |
||||
assertFalse(ExpressionEvaluator.eval(1, ">=", "2")); |
||||
assertFalse(ExpressionEvaluator.eval(2, "<", "1")); |
||||
assertFalse(ExpressionEvaluator.eval(2, "<=", "1")); |
||||
assertFalse(ExpressionEvaluator.eval(1, "==", "2")); |
||||
assertFalse(ExpressionEvaluator.eval(1, "!=", "1")); |
||||
} |
||||
|
||||
@Test |
||||
public void bigint_eval() throws Exception { |
||||
|
||||
assertTrue(ExpressionEvaluator.eval(new BigInteger("1"), "==", "1")); |
||||
assertTrue(ExpressionEvaluator.eval(new BigInteger("2"), "!=", "1")); |
||||
assertTrue(ExpressionEvaluator.eval(new BigInteger("2"), ">", "1")); |
||||
assertTrue(ExpressionEvaluator.eval(new BigInteger("2"), ">=", "1")); |
||||
assertTrue(ExpressionEvaluator.eval(new BigInteger("2"), ">=", "2")); |
||||
assertTrue(ExpressionEvaluator.eval(new BigInteger("1"), "<", "2")); |
||||
assertTrue(ExpressionEvaluator.eval(new BigInteger("2"), "<=", "2")); |
||||
|
||||
assertFalse(ExpressionEvaluator.eval(new BigInteger("1"), ">", "2")); |
||||
assertFalse(ExpressionEvaluator.eval(new BigInteger("1"), ">=", "2")); |
||||
assertFalse(ExpressionEvaluator.eval(new BigInteger("2"), "<", "1")); |
||||
assertFalse(ExpressionEvaluator.eval(new BigInteger("2"), "<=", "1")); |
||||
assertFalse(ExpressionEvaluator.eval(new BigInteger("1"), "==", "2")); |
||||
assertFalse(ExpressionEvaluator.eval(new BigInteger("1"), "!=", "1")); |
||||
} |
||||
|
||||
@Test |
||||
public void bigdec_eval() throws Exception { |
||||
|
||||
assertTrue(ExpressionEvaluator.eval(new BigDecimal("1.1"), "==", "1.1")); |
||||
assertTrue(ExpressionEvaluator.eval(new BigDecimal("2"), "!=", "1")); |
||||
assertTrue(ExpressionEvaluator.eval(new BigDecimal("2"), ">", "1")); |
||||
assertTrue(ExpressionEvaluator.eval(new BigDecimal("2"), ">=", "1")); |
||||
assertTrue(ExpressionEvaluator.eval(new BigDecimal("2"), ">=", "2")); |
||||
assertTrue(ExpressionEvaluator.eval(new BigDecimal("1"), "<", "2")); |
||||
assertTrue(ExpressionEvaluator.eval(new BigDecimal("2"), "<=", "2")); |
||||
|
||||
assertFalse(ExpressionEvaluator.eval(new BigDecimal("1"), ">", "2")); |
||||
assertFalse(ExpressionEvaluator.eval(new BigDecimal("1"), ">=", "2")); |
||||
assertFalse(ExpressionEvaluator.eval(new BigDecimal("2"), "<", "1")); |
||||
assertFalse(ExpressionEvaluator.eval(new BigDecimal("2"), "<=", "1")); |
||||
assertFalse(ExpressionEvaluator.eval(new BigDecimal("1"), "==", "2")); |
||||
assertFalse(ExpressionEvaluator.eval(new BigDecimal("1"), "!=", "1")); |
||||
} |
||||
|
||||
|
||||
@Test |
||||
public void double_eval() throws Exception { |
||||
|
||||
assertTrue(ExpressionEvaluator.eval(1D, "==", "1")); |
||||
assertTrue(ExpressionEvaluator.eval(2D, "!=", "1")); |
||||
assertTrue(ExpressionEvaluator.eval(2D, ">", "1")); |
||||
assertTrue(ExpressionEvaluator.eval(2D, ">=", "1")); |
||||
assertTrue(ExpressionEvaluator.eval(2D, ">=", "2")); |
||||
assertTrue(ExpressionEvaluator.eval(1D, "<", "2")); |
||||
assertTrue(ExpressionEvaluator.eval(2D, "<=", "2")); |
||||
|
||||
assertFalse(ExpressionEvaluator.eval(1D, ">", "2")); |
||||
assertFalse(ExpressionEvaluator.eval(1D, ">=", "2")); |
||||
assertFalse(ExpressionEvaluator.eval(2D, "<", "1")); |
||||
assertFalse(ExpressionEvaluator.eval(2D, "<=", "1")); |
||||
assertFalse(ExpressionEvaluator.eval(1D, "==", "2")); |
||||
assertFalse(ExpressionEvaluator.eval(1D, "!=", "1")); |
||||
} |
||||
|
||||
@Test |
||||
public void string_eval() throws Exception { |
||||
|
||||
assertTrue(ExpressionEvaluator.eval("A", "==", "A")); |
||||
assertTrue(ExpressionEvaluator.eval("B", "!=", "A")); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void boolean_eval() throws Exception { |
||||
|
||||
assertTrue(ExpressionEvaluator.eval(true, "==", "true")); |
||||
assertTrue(ExpressionEvaluator.eval(false, "==", "false")); |
||||
assertTrue(ExpressionEvaluator.eval(true, "!=", "false")); |
||||
assertTrue(ExpressionEvaluator.eval(true, "<>", "false")); |
||||
assertTrue(ExpressionEvaluator.eval(false, "!=", "true")); |
||||
assertTrue(ExpressionEvaluator.eval(false, "<>", "true")); |
||||
|
||||
assertFalse(ExpressionEvaluator.eval(true, "==", "false")); |
||||
assertFalse(ExpressionEvaluator.eval(false, "==", "true")); |
||||
assertFalse(ExpressionEvaluator.eval(true, "!=", "true")); |
||||
assertFalse(ExpressionEvaluator.eval(true, "<>", "true")); |
||||
assertFalse(ExpressionEvaluator.eval(false, "<>", "false")); |
||||
assertFalse(ExpressionEvaluator.eval(false, "!=", "false")); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void null_eval() throws Exception { |
||||
assertTrue(ExpressionEvaluator.eval(new Integer(10), "!=", "null")); |
||||
|
||||
assertTrue(ExpressionEvaluator.eval(null, "==", "null")); |
||||
|
||||
assertTrue(ExpressionEvaluator.eval(null, "<>", "FOO")); |
||||
assertTrue(ExpressionEvaluator.eval("FOO", "<>", "null")); |
||||
|
||||
|
||||
assertTrue(ExpressionEvaluator.eval(null, "!=", "FOO")); |
||||
assertTrue(ExpressionEvaluator.eval("FOO", "<>", "null")); |
||||
|
||||
assertTrue(ExpressionEvaluator.eval(null, "!=", "10")); |
||||
} |
||||
|
||||
@Test |
||||
public void and_operator_in_filter() { |
||||
|
||||
Object o = JsonPath.read(DOCUMENT, "$.characters[?(@.name == 'Luke Skywalker' && @.occupation == 'Farm boy')]"); |
||||
|
||||
assertThat((String)JsonPath.read(o, "[0].name"), is("Luke Skywalker")); |
||||
assertThat((String)JsonPath.read(o, "[0].occupation"), is("Farm boy")); |
||||
} |
||||
|
||||
@Test |
||||
public void not_equal_in_and_operator_filter() { |
||||
|
||||
|
||||
Object o = JsonPath.read(DOCUMENT, "$.characters[?(@.name == 'Luke Skywalker' && @.occupation != 'Farm boy')]"); |
||||
assertEquals("[]", o.toString()); |
||||
|
||||
o = JsonPath.read(DOCUMENT, "$.characters[?(@.name == 'Luke Skywalker' && @.occupation != 'City boy')]"); |
||||
|
||||
assertThat((String)JsonPath.read(o, "[0].name"), is("Luke Skywalker")); |
||||
assertThat((String)JsonPath.read(o, "[0].occupation"), CoreMatchers.not("City boy")); |
||||
} |
||||
|
||||
@Test |
||||
public void nulls_filter() { |
||||
|
||||
//List<Map<String, Object>> result = JsonPath.read(DOCUMENT, "$.characters[?(@.offspring == null)]");
|
||||
//List<Map<String, Object>> result = JsonPath.read(DOCUMENT, "$.characters[?]", Filter.filter(Criteria.where("offspring").is(null)));
|
||||
//assertEquals(2, result.size());
|
||||
|
||||
|
||||
// result = JsonPath.read(DOCUMENT, "$.characters[?]", filter(where("offspring").exists(false)));
|
||||
// System.out.println(result);
|
||||
// assertEquals(1, result.size());
|
||||
//
|
||||
//
|
||||
// result = JsonPath.read(DOCUMENT, "$.characters[?(@.offspring != null)]");
|
||||
// assertEquals(3, result.size());
|
||||
//
|
||||
// result = JsonPath.read(DOCUMENT, "$.characters[?(@.offspring)]");
|
||||
// assertEquals(4, result.size());
|
||||
|
||||
|
||||
PathEvaluationResult res = PathEvaluator.evaluate("$.characters[?(@.offspring != null)]", DOCUMENT, JsonProviderFactory.createProvider(), Collections.EMPTY_SET, new Filter[0]); |
||||
|
||||
logger.debug(res.toString()); |
||||
|
||||
} |
||||
*/ |
||||
|
||||
|
||||
} |
@ -0,0 +1,55 @@
|
||||
package com.jayway.jsonpath; |
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference; |
||||
import org.junit.Test; |
||||
|
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Optional; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
@SuppressWarnings("ALL") |
||||
public class ReturnTypeTest extends BaseTest { |
||||
|
||||
@Test |
||||
public void assert_strings_can_be_read() { |
||||
assertThat(JsonPath.read(JSON_DOCUMENT, "$.string-property")).isEqualTo("string-value"); |
||||
} |
||||
|
||||
@Test |
||||
public void assert_ints_can_be_read() { |
||||
assertThat(JsonPath.read(JSON_DOCUMENT, "$.int-property")).isEqualTo(Integer.MAX_VALUE); |
||||
} |
||||
|
||||
@Test |
||||
public void assert_longs_can_be_read() { |
||||
assertThat(JsonPath.read(JSON_DOCUMENT, "$.long-property")).isEqualTo(Long.MAX_VALUE); |
||||
} |
||||
|
||||
@Test |
||||
public void assert_boolean_values_can_be_read() { |
||||
assertThat(JsonPath.read(JSON_DOCUMENT, "$.boolean-property")).isEqualTo(true); |
||||
} |
||||
|
||||
@Test |
||||
public void assert_null_values_can_be_read() { |
||||
assertThat(JsonPath.read(JSON_DOCUMENT, "$.null-property")).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
public void assert_arrays_can_be_read_2() { |
||||
List<Object> list = JsonPath.read(JSON_DOCUMENT, "$.store.book"); |
||||
|
||||
assertThat(list).hasSize(4); |
||||
} |
||||
|
||||
@Test |
||||
public void assert_maps_can_be_read() { |
||||
assertThat(JsonPath.read(JSON_DOCUMENT, "$.store.book[0]", Map.class)) |
||||
.containsEntry("category", "reference") |
||||
.containsEntry("author", "Nigel Rees") |
||||
.containsEntry("title", "Sayings of the Century") |
||||
.containsEntry("display-price", 8.95D); |
||||
} |
||||
} |
@ -1,55 +0,0 @@
|
||||
package com.jayway.jsonpath; |
||||
|
||||
/** |
||||
* |
||||
*/ |
||||
public class Runner { |
||||
|
||||
public final static String DOCUMENT = |
||||
"{ \"store\": {\n" + |
||||
" \"book\": [ \n" + |
||||
" { \"category\": \"reference\",\n" + |
||||
" \"author\": \"Nigel Rees\",\n" + |
||||
" \"title\": \"Sayings of the Century\",\n" + |
||||
" \"price\": 8.95\n" + |
||||
" },\n" + |
||||
" { \"category\": \"fiction\",\n" + |
||||
" \"author\": \"Evelyn Waugh\",\n" + |
||||
" \"title\": \"Sword of Honour\",\n" + |
||||
" \"price\": 12.99\n" + |
||||
" },\n" + |
||||
" { \"category\": \"fiction\",\n" + |
||||
" \"author\": \"Herman Melville\",\n" + |
||||
" \"title\": \"Moby Dick\",\n" + |
||||
" \"isbn\": \"0-553-21311-3\",\n" + |
||||
" \"price\": 8.99\n" + |
||||
" },\n" + |
||||
" { \"category\": \"fiction\",\n" + |
||||
" \"author\": \"J. R. R. Tolkien\",\n" + |
||||
" \"title\": \"The Lord of the Rings\",\n" + |
||||
" \"isbn\": \"0-395-19395-8\",\n" + |
||||
" \"price\": 22.99\n" + |
||||
" }\n" + |
||||
" ],\n" + |
||||
" \"bicycle\": {\n" + |
||||
" \"color\": \"red\",\n" + |
||||
" \"price\": 19.95,\n" + |
||||
" \"foo:bar\": \"fooBar\",\n" + |
||||
" \"dot.notation\": \"new\"\n" + |
||||
" }\n" + |
||||
" }\n" + |
||||
"}"; |
||||
|
||||
public static void main(String[] args) { |
||||
|
||||
JsonPath jp = JsonPath.compile("$.store.book[*].category"); |
||||
ReadContext readContext = JsonPath.parse(DOCUMENT); |
||||
long start = System.currentTimeMillis(); |
||||
for (long i = 0; i < 50000000; i++) { |
||||
|
||||
readContext.read(jp); |
||||
} |
||||
System.out.println(System.currentTimeMillis() - start); |
||||
|
||||
} |
||||
} |
@ -1,93 +0,0 @@
|
||||
package com.jayway.jsonpath.internal2; |
||||
|
||||
public class ArrayPathFragmentTest { |
||||
/* |
||||
private static final Logger logger = LoggerFactory.getLogger(ArrayPathFragmentTest.class); |
||||
|
||||
private JsonProvider jsonProvider = JsonProviderFactory.createProvider(); |
||||
|
||||
private String SIMPLE_ARRAY = "[" + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-0\"\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-1\"\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-2\"\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-3\"\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-4\"\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-5\"\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-6\"\n" + |
||||
"}" + |
||||
"]"; |
||||
|
||||
@Test |
||||
public void array_can_select_single_index_by_context_length() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$[(@.length-1)]", SIMPLE_ARRAY, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertEquals("{\"foo\":\"foo-val-6\"}", result.getJson()); |
||||
} |
||||
|
||||
@Test |
||||
public void array_can_select_multiple_indexes() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$[0,1]", SIMPLE_ARRAY, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertEquals("[{\"foo\":\"foo-val-0\"},{\"foo\":\"foo-val-1\"}]", result.getJson()); |
||||
} |
||||
|
||||
@Test |
||||
public void array_can_be_sliced_to_2() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$[:2]", SIMPLE_ARRAY, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertEquals("[{\"foo\":\"foo-val-0\"},{\"foo\":\"foo-val-1\"}]", result.getJson()); |
||||
|
||||
System.out.println(result.getPathList().toString()); |
||||
|
||||
logger.debug(result.toString()); |
||||
} |
||||
|
||||
@Test |
||||
public void array_can_be_sliced_to_2_from_tail() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$[:-5]", SIMPLE_ARRAY, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertEquals("[{\"foo\":\"foo-val-0\"},{\"foo\":\"foo-val-1\"}]", result.getJson()); |
||||
} |
||||
|
||||
@Test |
||||
public void array_can_be_sliced_from_2() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$[5:]", SIMPLE_ARRAY, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertEquals("[{\"foo\":\"foo-val-5\"},{\"foo\":\"foo-val-6\"}]", result.getJson()); |
||||
} |
||||
|
||||
@Test |
||||
public void array_can_be_sliced_from_2_from_tail() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$[-2:]", SIMPLE_ARRAY, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertEquals("[{\"foo\":\"foo-val-5\"},{\"foo\":\"foo-val-6\"}]", result.getJson()); |
||||
} |
||||
|
||||
@Test |
||||
public void array_can_be_sliced_between() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$[2:4]", SIMPLE_ARRAY, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertEquals("[{\"foo\":\"foo-val-2\"},{\"foo\":\"foo-val-3\"}]", result.getJson()); |
||||
} |
||||
*/ |
||||
} |
@ -1,164 +0,0 @@
|
||||
package com.jayway.jsonpath.internal2; |
||||
|
||||
import com.jayway.jsonpath.spi.json.JsonProvider; |
||||
import com.jayway.jsonpath.spi.json.JsonProviderFactory; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
public class DeepScanPathFragmentTest { |
||||
|
||||
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DeepScanPathFragmentTest.class); |
||||
|
||||
private JsonProvider jsonProvider = JsonProviderFactory.createProvider(); |
||||
|
||||
private static final String DOCUMENT = "{\n" + |
||||
" \"store\":{\n" + |
||||
" \"book\":[\n" + |
||||
" {\n" + |
||||
" \"category\":\"reference\",\n" + |
||||
" \"author\":\"Nigel Rees\",\n" + |
||||
" \"title\":\"Sayings of the Century\",\n" + |
||||
" \"price\":8.95,\n" + |
||||
" \"address\":{ " + |
||||
" \"street\":\"fleet street\",\n" + |
||||
" \"city\":\"London\"\n" + |
||||
" }\n" + |
||||
" },\n" + |
||||
" {\n" + |
||||
" \"category\":\"fiction\",\n" + |
||||
" \"author\":\"Evelyn Waugh\",\n" + |
||||
" \"title\":\"Sword of Honour\",\n" + |
||||
" \"price\":12.9,\n" + |
||||
" \"address\":{ \n" + |
||||
" \"street\":\"Baker street\",\n" + |
||||
" \"city\":\"London\"\n" + |
||||
" }\n" + |
||||
" },\n" + |
||||
" {\n" + |
||||
" \"category\":\"fiction\",\n" + |
||||
" \"author\":\"J. R. R. Tolkien\",\n" + |
||||
" \"title\":\"The Lord of the Rings\",\n" + |
||||
" \"isbn\":\"0-395-19395-8\",\n" + |
||||
" \"price\":22.99," + |
||||
" \"address\":{ " + |
||||
" \"street\":\"Svea gatan\",\n" + |
||||
" \"city\":\"Stockholm\"\n" + |
||||
" }\n" + |
||||
" }\n" + |
||||
" ],\n" + |
||||
" \"bicycle\":{\n" + |
||||
" \"color\":\"red\",\n" + |
||||
" \"price\":19.95," + |
||||
" \"address\":{ " + |
||||
" \"street\":\"Söder gatan\",\n" + |
||||
" \"city\":\"Stockholm\"\n" + |
||||
" },\n" + |
||||
" \"items\": [[\"A\",\"B\",\"C\"],1,2,3,4,5]\n" + |
||||
" }\n" + |
||||
" }\n" + |
||||
"}"; |
||||
|
||||
private static final String DOCUMENT2 = "{\n" + |
||||
" \"firstName\": \"John\",\n" + |
||||
" \"lastName\" : \"doe\",\n" + |
||||
" \"age\" : 26,\n" + |
||||
" \"address\" :\n" + |
||||
" {\n" + |
||||
" \"streetAddress\": \"naist street\",\n" + |
||||
" \"city\" : \"Nara\",\n" + |
||||
" \"postalCode\" : \"630-0192\"\n" + |
||||
" },\n" + |
||||
" \"phoneNumbers\":\n" + |
||||
" [\n" + |
||||
" {\n" + |
||||
" \"type\" : \"iPhone\",\n" + |
||||
" \"number\": \"0123-4567-8888\"\n" + |
||||
" },\n" + |
||||
" {\n" + |
||||
" \"type\" : \"home\",\n" + |
||||
" \"number\": \"0123-4567-8910\"\n" + |
||||
" }\n" + |
||||
" ]\n" + |
||||
" }\n" + |
||||
" "; |
||||
|
||||
/* |
||||
@Test |
||||
public void a_document_can_be_scanned_for_property() { |
||||
|
||||
// $..['author'] - PropertyPathComponent
|
||||
// $..[*] - PropertyWildcardComponent
|
||||
// $..[1] [1,2,3] - ArrayPathComponent
|
||||
// $..[?(@.name)] - FilterPredicatePathComponent
|
||||
|
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$..author", DOCUMENT, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertEquals("[\"Nigel Rees\",\"Evelyn Waugh\",\"J. R. R. Tolkien\"]", result.getJson()); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void a_document_can_be_scanned_for_property_path() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$..address.street", DOCUMENT, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertEquals("[\"fleet street\",\"Baker street\",\"Svea gatan\",\"Söder gatan\"]", result.getJson()); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void a_document_can_be_scanned_for_wildcard() { |
||||
|
||||
PathEvaluationResult result1 = PathEvaluator.evaluate("$..[*]", DOCUMENT, jsonProvider, Collections.EMPTY_SET); |
||||
PathEvaluationResult result2 = PathEvaluator.evaluate("$..*", DOCUMENT, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertTrue(result1.getPathList().equals(result2.getPathList())); |
||||
|
||||
logger.debug(result1.toString()); |
||||
} |
||||
|
||||
@Test |
||||
public void a_document_can_be_scanned_for_wildcard2() { |
||||
//ISSUE
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$.store.book[0]..*", DOCUMENT, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
logger.debug(result.toString()); |
||||
} |
||||
|
||||
@Test |
||||
public void a_document_can_be_scanned_for_wildcard3() { |
||||
//ISSUE
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$.phoneNumbers[0]..*", DOCUMENT2, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
logger.debug(result.toString()); |
||||
} |
||||
|
||||
@Test |
||||
public void a_document_can_be_scanned_for_predicate_match() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$..[?(@.address.city == 'Stockholm')]", DOCUMENT, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
logger.debug(result.toString()); |
||||
} |
||||
|
||||
@Test |
||||
public void a_document_can_be_scanned_for_existence() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$..[?(@.isbn)]", DOCUMENT, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
logger.debug(result.toString()); |
||||
} |
||||
|
||||
@Test |
||||
public void a_document_can_be_scanned_for_array_indexes() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$..[(@.length - 1)]", DOCUMENT, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
logger.debug(result.toString()); |
||||
logger.debug(result.getPathList().toString()); |
||||
} |
||||
*/ |
||||
} |
@ -1,131 +0,0 @@
|
||||
package com.jayway.jsonpath.internal2; |
||||
|
||||
import com.jayway.jsonpath.spi.json.JsonProvider; |
||||
import com.jayway.jsonpath.spi.json.JsonProviderFactory; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
public class FilterPredicatePathFragmentTest { |
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(FilterPredicatePathFragmentTest.class); |
||||
|
||||
private JsonProvider jsonProvider = JsonProviderFactory.createProvider(); |
||||
|
||||
private String SIMPLE_ARRAY = "[" + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-0\"\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-1\"\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-2\"\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-3\"\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-4\"\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-5\"\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-6\"\n" + |
||||
"}" + |
||||
"]"; |
||||
|
||||
private String SIMPLE_ARRAY_2 = "[" + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-0\",\n" + |
||||
" \"int\" : 0\n," + |
||||
" \"decimal\" : 0.0\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-1\",\n" + |
||||
" \"int\" : 1,\n" + |
||||
" \"decimal\" : 0.1\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-2\",\n" + |
||||
" \"int\" : 2,\n" + |
||||
" \"decimal\" : 0.2\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-3\",\n" + |
||||
" \"int\" : 3,\n" + |
||||
" \"decimal\" : 0.3\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-4\",\n" + |
||||
" \"int\" : 4,\n" + |
||||
" \"decimal\" : 0.4\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-5\",\n" + |
||||
" \"int\" : 5,\n" + |
||||
" \"decimal\" : 0.5\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-6\",\n" + |
||||
" \"int\" : 6,\n" + |
||||
" \"decimal\" : 0.6\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-7\",\n" + |
||||
" \"int\" : 7,\n" + |
||||
" \"decimal\" : 0.7,\n" + |
||||
" \"bool\" : true\n" + |
||||
"}" + |
||||
"]"; |
||||
|
||||
/* |
||||
@Test |
||||
public void a_filter_predicate_can_be_evaluated_on_string_criteria() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$[?(@.foo == 'foo-val-1')]", SIMPLE_ARRAY, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertThat((String)JsonPath.read(result.getResult(), "[0].foo"), is("foo-val-1")); |
||||
} |
||||
|
||||
@Test |
||||
public void a_filter_predicate_can_be_evaluated_on_int_criteria() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$[?(@.int == 1)]", SIMPLE_ARRAY_2, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertThat((String)JsonPath.read(result.getResult(), "[0].foo"), is("foo-val-1")); |
||||
} |
||||
|
||||
@Test |
||||
public void a_filter_predicate_can_be_evaluated_on_decimal_criteria() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$[?(@.decimal == 0.1)]", SIMPLE_ARRAY_2, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertThat((String)JsonPath.read(result.getResult(), "[0].foo"), is("foo-val-1")); |
||||
} |
||||
|
||||
@Test |
||||
public void multiple_criteria_can_be_used() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$[?(@.decimal == 0.1 && @.int == 1)]", SIMPLE_ARRAY_2, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertThat((String)JsonPath.read(result.getResult(), "[0].foo"), is("foo-val-1")); |
||||
} |
||||
|
||||
@Test |
||||
public void field_existence_can_be_checked() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$[?(@.bool)]", SIMPLE_ARRAY_2, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertThat((String)JsonPath.read(result.getResult(), "[0].foo"), is("foo-val-7")); |
||||
} |
||||
|
||||
@Test |
||||
public void boolean_criteria_evaluates() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$[?(@.bool == true)]", SIMPLE_ARRAY_2, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertThat((String)JsonPath.read(result.getResult(), "[0].foo"), is("foo-val-7")); |
||||
} |
||||
*/ |
||||
} |
@ -1,65 +0,0 @@
|
||||
package com.jayway.jsonpath.internal2; |
||||
|
||||
public class PathCompilerTest { |
||||
|
||||
/* |
||||
@Test |
||||
public void a_path_can_be_formalized() { |
||||
|
||||
assertEquals("$[*]['category', 'title']", PathCompiler.compile("$[*].['category', 'title']").getPath()); |
||||
assertEquals("$['foo'][*]", PathCompiler.compile("foo.*").getPath()); |
||||
assertEquals("$[?(@.decimal == 0.1 && @.int == 1)]", PathCompiler.compile("$[?(@.decimal == 0.1 && @.int == 1)]").getPath()); |
||||
assertEquals("$['foo']['bar'][?(@.foo == 'bar')]['prop']", PathCompiler.compile("$.foo.bar[?(@.foo == 'bar')].prop").getPath()); |
||||
assertEquals("$['foo','bar']['bar'][1,2,3]", PathCompiler.compile("['foo','bar'].bar[1,2,3]").getPath()); |
||||
assertEquals("$['foo','bar']['bar'][-1:]", PathCompiler.compile("['foo','bar'].bar[-1:]").getPath()); |
||||
assertEquals("$['foo','bar']['bar'][1]", PathCompiler.compile("['foo','bar'].bar[1]").getPath()); |
||||
assertEquals("$['foo','bar']['bar'][:1]", PathCompiler.compile("['foo','bar'].bar[:1]").getPath()); |
||||
assertEquals("$['foo','bar']['bar'][0:5]", PathCompiler.compile("['foo','bar'].bar[0:5]").getPath()); |
||||
assertEquals("$['foo']..['bar'][1]", PathCompiler.compile("foo..bar[1]").getPath()); |
||||
assertEquals("$['foo']['bar'][1]", PathCompiler.compile("foo.bar[1]").getPath()); |
||||
assertEquals("$['foo']['bar'][1]", PathCompiler.compile("$.foo.bar[1]").getPath()); |
||||
assertEquals("$['foo']['bar'][1,2,3]", PathCompiler.compile("$.foo.bar[1,2,3]").getPath()); |
||||
assertEquals("$['foo']['bar'][1]['prop']", PathCompiler.compile("$.foo.bar[1].prop").getPath()); |
||||
assertEquals("$['foo']['fiz']['bar'][1]", PathCompiler.compile("$.foo['fiz'].bar[1]").getPath()); |
||||
assertEquals("$['foo']['fiz']['bar'][1]['next']", PathCompiler.compile("$.foo['fiz'].bar[1].next").getPath()); |
||||
assertEquals("$['foo']['fiz']['bar'][1]['next']", PathCompiler.compile("$['foo']['fiz']['bar'][1]['next']").getPath()); |
||||
assertEquals("$['foo']['bar'][?(@['foo'] == 'bar')]['prop']", PathCompiler.compile("$.foo.bar[?(@['foo'] == 'bar')].prop").getPath()); |
||||
} |
||||
|
||||
@Test(expected = InvalidPathException.class) |
||||
public void function_brackets_must_match() { |
||||
PathCompiler.compile("$[?(@.decimal == 0.1 && @.int == 1]"); |
||||
} |
||||
|
||||
@Test |
||||
public void property_fragment_can_be_analyzed() { |
||||
PathCompiler.PathComponentAnalyzer.analyze("['foo','bar']"); |
||||
} |
||||
|
||||
@Test |
||||
public void number_fragment_can_be_analyzed() { |
||||
|
||||
PathCompiler.PathComponentAnalyzer.analyze("[*]"); |
||||
PathCompiler.PathComponentAnalyzer.analyze("[(@.size() - 1)]"); |
||||
PathCompiler.PathComponentAnalyzer.analyze("[(@.length-2)]"); |
||||
PathCompiler.PathComponentAnalyzer.analyze("[1]"); |
||||
PathCompiler.PathComponentAnalyzer.analyze("[1,2,3]"); |
||||
PathCompiler.PathComponentAnalyzer.analyze("[:1]"); |
||||
PathCompiler.PathComponentAnalyzer.analyze("[-1:]"); |
||||
PathCompiler.PathComponentAnalyzer.analyze("[0:1]"); |
||||
} |
||||
|
||||
@Test |
||||
public void criteria_can_be_analyzed() { |
||||
|
||||
PathCompiler.PathComponentAnalyzer.analyze("[?(@ == 'bar' && @.size == 1)]"); |
||||
PathCompiler.PathComponentAnalyzer.analyze("[?(@.foo)]"); |
||||
PathCompiler.PathComponentAnalyzer.analyze("[ ?(@.foo) ]"); |
||||
PathCompiler.PathComponentAnalyzer.analyze("[ ?( @.foo ) ]"); |
||||
PathCompiler.PathComponentAnalyzer.analyze("[?(@.foo)]"); |
||||
PathCompiler.PathComponentAnalyzer.analyze("[?(@.foo == 'bar')]"); |
||||
PathCompiler.PathComponentAnalyzer.analyze("[?(@['foo']['bar'] == 'bar')]"); |
||||
PathCompiler.PathComponentAnalyzer.analyze("[?(@ == 'bar')]"); |
||||
} |
||||
*/ |
||||
} |
@ -1,113 +0,0 @@
|
||||
package com.jayway.jsonpath.internal2; |
||||
|
||||
import com.jayway.jsonpath.spi.json.JsonProvider; |
||||
import com.jayway.jsonpath.spi.json.JsonProviderFactory; |
||||
|
||||
public class PathWalkerTest { |
||||
|
||||
private JsonProvider jsonProvider = JsonProviderFactory.createProvider(); |
||||
|
||||
private static final String DOCUMENT = "{\n" + |
||||
" \"store\":{\n" + |
||||
" \"book\":[\n" + |
||||
" {\n" + |
||||
" \"category\":\"reference\",\n" + |
||||
" \"author\":\"Nigel Rees\",\n" + |
||||
" \"title\":\"Sayings of the Century\",\n" + |
||||
" \"price\":8.95\n" + |
||||
" },\n" + |
||||
" {\n" + |
||||
" \"category\":\"fiction\",\n" + |
||||
" \"author\":\"Evelyn Waugh\",\n" + |
||||
" \"title\":\"Sword of Honour\",\n" + |
||||
" \"price\":12.99\n" + |
||||
" },\n" + |
||||
" {\n" + |
||||
" \"category\":\"fiction\",\n" + |
||||
" \"author\":\"J. R. R. Tolkien\",\n" + |
||||
" \"title\":\"The Lord of the Rings\",\n" + |
||||
" \"isbn\":\"0-395-19395-8\",\n" + |
||||
" \"price\":22.99\n" + |
||||
" }\n" + |
||||
" ],\n" + |
||||
" \"bicycle\":{\n" + |
||||
" \"color\":\"red\",\n" + |
||||
" \"price\":19.95\n" + |
||||
" }\n" + |
||||
" }\n" + |
||||
"}"; |
||||
/* |
||||
|
||||
@Test |
||||
public void a_definite_path_can_be_evaluated() { |
||||
|
||||
Object model = jsonProvider.parse(DOCUMENT); |
||||
|
||||
Path path = PathCompiler.compile("$['store']['bicycle']"); |
||||
|
||||
PathWalker walker = new PathWalker(jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
walker.walk(path, model); |
||||
} |
||||
|
||||
@Test |
||||
public void a_path_can_be_evaluated_with_array_wildcard() { |
||||
|
||||
Object model = jsonProvider.parse(DOCUMENT); |
||||
|
||||
Path path = PathCompiler.compile("$['store']['book'][*]"); |
||||
|
||||
PathWalker walker = new PathWalker(jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
walker.walk(path, model); |
||||
} |
||||
|
||||
@Test |
||||
public void a_path_can_be_evaluated_with_array_sequence() { |
||||
|
||||
Object model = jsonProvider.parse(DOCUMENT); |
||||
|
||||
Path path = PathCompiler.compile("$['store']['book'][0,2]"); |
||||
|
||||
PathWalker walker = new PathWalker(jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
walker.walk(path, model); |
||||
} |
||||
|
||||
@Test |
||||
public void a_path_can_be_evaluated_with_slice_from() { |
||||
|
||||
Object model = jsonProvider.parse(DOCUMENT); |
||||
|
||||
Path path = PathCompiler.compile("$['store']['book'][2:]"); |
||||
|
||||
PathWalker walker = new PathWalker(jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
walker.walk(path, model); |
||||
} |
||||
|
||||
@Test |
||||
public void a_path_can_be_evaluated_with_filter() { |
||||
|
||||
Object model = jsonProvider.parse(DOCUMENT); |
||||
|
||||
Path path = PathCompiler.compile("$['store']['book'][?(@['category'] == 'fiction')]"); |
||||
|
||||
PathWalker walker = new PathWalker(jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
walker.walk(path, model); |
||||
} |
||||
|
||||
@Test |
||||
public void a_path_can_be_evaluated_property_wildcard_on_object() { |
||||
|
||||
Object model = jsonProvider.parse(DOCUMENT); |
||||
|
||||
Path path = PathCompiler.compile("$['store']['book'][1].*"); |
||||
|
||||
PathWalker walker = new PathWalker(jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
walker.walk(path, model); |
||||
} |
||||
*/ |
||||
} |
@ -1,75 +0,0 @@
|
||||
package com.jayway.jsonpath.internal2; |
||||
|
||||
import com.jayway.jsonpath.spi.json.JsonProvider; |
||||
import com.jayway.jsonpath.spi.json.JsonProviderFactory; |
||||
|
||||
public class WildcardPathFragmentTest { |
||||
|
||||
|
||||
private JsonProvider jsonProvider = JsonProviderFactory.createProvider(); |
||||
|
||||
private String ARRAY = "[" + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-0\",\n" + |
||||
" \"int\" : 0\n," + |
||||
" \"decimal\" : 0.0\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-1\",\n" + |
||||
" \"int\" : 1,\n" + |
||||
" \"decimal\" : 0.1\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-2\",\n" + |
||||
" \"int\" : 2,\n" + |
||||
" \"decimal\" : 0.2\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-3\",\n" + |
||||
" \"int\" : 3,\n" + |
||||
" \"decimal\" : 0.3\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-4\",\n" + |
||||
" \"int\" : 4,\n" + |
||||
" \"decimal\" : 0.4\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-5\",\n" + |
||||
" \"int\" : 5,\n" + |
||||
" \"decimal\" : 0.5\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-6\",\n" + |
||||
" \"int\" : 6,\n" + |
||||
" \"decimal\" : 0.6\n" + |
||||
"}," + |
||||
"{\n" + |
||||
" \"foo\" : \"foo-val-7\",\n" + |
||||
" \"int\" : 7,\n" + |
||||
" \"decimal\" : 0.7,\n" + |
||||
" \"bool\" : true\n" + |
||||
"}" + |
||||
"]"; |
||||
|
||||
/* |
||||
@Test |
||||
public void wildcard_on_array_returns_all_items() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$[*]", ARRAY, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertTrue(jsonProvider.isArray(result.getResult())); |
||||
assertEquals(8, jsonProvider.length(result.getResult())); |
||||
|
||||
} |
||||
@Test |
||||
public void wildcard_on_map_returns_all_attribute_values() { |
||||
|
||||
PathEvaluationResult result = PathEvaluator.evaluate("$[1].*", ARRAY, jsonProvider, Collections.EMPTY_SET); |
||||
|
||||
assertTrue(jsonProvider.isArray(result.getResult())); |
||||
assertEquals(3, jsonProvider.length(result.getResult())); |
||||
} |
||||
*/ |
||||
|
||||
} |
@ -1,5 +1,6 @@
|
||||
package com.jayway.jsonpath; |
||||
package com.jayway.jsonpath.old; |
||||
|
||||
import com.jayway.jsonpath.JsonPath; |
||||
import org.hamcrest.Matchers; |
||||
import org.junit.Test; |
||||
|
@ -1,5 +1,6 @@
|
||||
package com.jayway.jsonpath; |
||||
package com.jayway.jsonpath.old; |
||||
|
||||
import com.jayway.jsonpath.JsonPath; |
||||
import org.hamcrest.Matchers; |
||||
import org.junit.Test; |
||||
|
@ -1,5 +1,6 @@
|
||||
package com.jayway.jsonpath; |
||||
package com.jayway.jsonpath.old; |
||||
|
||||
import com.jayway.jsonpath.Option; |
||||
import com.jayway.jsonpath.spi.json.JsonProvider; |
||||
import com.jayway.jsonpath.spi.json.JsonProviderFactory; |
||||
|
@ -1,5 +1,6 @@
|
||||
package com.jayway.jsonpath; |
||||
package com.jayway.jsonpath.old; |
||||
|
||||
import com.jayway.jsonpath.JsonPath; |
||||
import org.junit.Test; |
||||
|
||||
public class DocumentationPageTests { |
@ -1,5 +1,7 @@
|
||||
package com.jayway.jsonpath; |
||||
package com.jayway.jsonpath.old; |
||||
|
||||
import com.jayway.jsonpath.Configuration; |
||||
import com.jayway.jsonpath.Predicate; |
||||
import org.junit.Test; |
||||
|
||||
import java.util.List; |
@ -1,5 +1,6 @@
|
||||
package com.jayway.jsonpath; |
||||
package com.jayway.jsonpath.old; |
||||
|
||||
import com.jayway.jsonpath.JsonPath; |
||||
import org.junit.Test; |
||||
|
||||
import java.util.List; |
@ -1,4 +1,4 @@
|
||||
package com.jayway.jsonpath; |
||||
package com.jayway.jsonpath.old; |
||||
|
||||
import com.jayway.jsonpath.internal.Utils; |
||||
import com.jayway.jsonpath.spi.http.HttpProviderFactory; |
@ -1,5 +1,11 @@
|
||||
package com.jayway.jsonpath; |
||||
|
||||
package com.jayway.jsonpath.old; |
||||
|
||||
import com.jayway.jsonpath.Configuration; |
||||
import com.jayway.jsonpath.Criteria; |
||||
import com.jayway.jsonpath.Filter; |
||||
import com.jayway.jsonpath.JsonPath; |
||||
import com.jayway.jsonpath.Option; |
||||
import com.jayway.jsonpath.PathNotFoundException; |
||||
import com.jayway.jsonpath.internal.Utils; |
||||
import com.jayway.jsonpath.spi.json.JsonProvider; |
||||
import com.jayway.jsonpath.spi.json.JsonProviderFactory; |
@ -1,4 +1,4 @@
|
||||
package com.jayway.jsonpath; |
||||
package com.jayway.jsonpath.old; |
||||
|
||||
public class JsonPathFilterTest { |
||||
|
@ -1,4 +1,4 @@
|
||||
package com.jayway.jsonpath; |
||||
package com.jayway.jsonpath.old; |
||||
|
||||
import com.jayway.jsonpath.internal.spi.json.JacksonProvider; |
||||
import org.junit.Test; |
@ -1,4 +1,4 @@
|
||||
package com.jayway.jsonpath; |
||||
package com.jayway.jsonpath.old; |
||||
|
||||
public class MultiAttributeTest { |
||||
|
@ -1,5 +1,9 @@
|
||||
package com.jayway.jsonpath; |
||||
package com.jayway.jsonpath.old; |
||||
|
||||
import com.jayway.jsonpath.Configuration; |
||||
import com.jayway.jsonpath.JsonPath; |
||||
import com.jayway.jsonpath.Option; |
||||
import com.jayway.jsonpath.PathNotFoundException; |
||||
import org.assertj.core.api.Assertions; |
||||
import org.junit.Test; |
||||
|
@ -1,4 +1,4 @@
|
||||
package com.jayway.jsonpath.internal; |
||||
package com.jayway.jsonpath.old.internal; |
||||
|
||||
import com.jayway.jsonpath.JsonPath; |
||||
import org.hamcrest.Matchers; |
@ -1,4 +1,4 @@
|
||||
package com.jayway.jsonpath.internal; |
||||
package com.jayway.jsonpath.old.internal; |
||||
|
||||
import org.junit.Test; |
||||
|
@ -1,4 +1,4 @@
|
||||
package com.jayway.jsonpath.internal; |
||||
package com.jayway.jsonpath.old.internal; |
||||
|
||||
import com.jayway.jsonpath.JsonPath; |
||||
import com.jayway.jsonpath.spi.json.JsonProviderFactory; |
@ -1,4 +1,4 @@
|
||||
package com.jayway.jsonpath.internal; |
||||
package com.jayway.jsonpath.old.internal; |
||||
|
||||
import com.jayway.jsonpath.Configuration; |
||||
import com.jayway.jsonpath.JsonPath; |
@ -1,4 +1,4 @@
|
||||
package com.jayway.jsonpath.internal; |
||||
package com.jayway.jsonpath.old.internal; |
||||
|
||||
import com.jayway.jsonpath.Configuration; |
||||
import com.jayway.jsonpath.spi.json.JsonProviderFactory; |
@ -1,4 +1,4 @@
|
||||
package com.jayway.jsonpath.reader; |
||||
package com.jayway.jsonpath.old.reader; |
||||
|
||||
import com.jayway.jsonpath.Configuration; |
||||
import com.jayway.jsonpath.JsonPath; |
@ -1,56 +0,0 @@
|
||||
package com.jayway.jsonpath.util; |
||||
|
||||
import javax.script.Invocable; |
||||
import javax.script.ScriptEngine; |
||||
import javax.script.ScriptEngineManager; |
||||
import javax.script.ScriptException; |
||||
|
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.util.Scanner; |
||||
|
||||
public class ScriptEngineJsonPath { |
||||
|
||||
private static ScriptEngineManager manager = new ScriptEngineManager(); |
||||
private static ScriptEngine engine = manager.getEngineByName("JavaScript"); |
||||
|
||||
private static final String JSON_PATH_SCRIPT = readScript("jsonpath-0.8.0.js"); |
||||
private static final String JSON_SCRIPT = readScript("json.js"); |
||||
private static final String WRAPPER_SCRIPT = readScript("wrapper.js"); |
||||
|
||||
static { |
||||
try { |
||||
engine.eval(JSON_PATH_SCRIPT); |
||||
engine.eval(JSON_SCRIPT); |
||||
engine.eval(WRAPPER_SCRIPT); |
||||
} catch (ScriptException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
|
||||
public static String eval(String json, String path) throws Exception { |
||||
Invocable inv = (Invocable) engine; |
||||
Object obj = engine.get("WRAPPER"); |
||||
return (String)inv.invokeMethod(obj, "jsonPath", json, path); |
||||
} |
||||
|
||||
|
||||
private static String readScript(String script) { |
||||
InputStream is = null; |
||||
try { |
||||
is = ScriptEngineJsonPath.class.getClassLoader().getSystemResourceAsStream("js/" + script); |
||||
|
||||
return new Scanner(is).useDelimiter("\\A").next(); |
||||
} finally { |
||||
if (is != null) { |
||||
try { |
||||
is.close(); |
||||
} catch (IOException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
@ -1,530 +0,0 @@
|
||||
/* |
||||
json.js |
||||
2011-08-30 |
||||
|
||||
Public Domain |
||||
|
||||
No warranty expressed or implied. Use at your own risk. |
||||
|
||||
This file has been superceded by http://www.JSON.org/json2.js
|
||||
|
||||
See http://www.JSON.org/js.html
|
||||
|
||||
This code should be minified before deployment. |
||||
See http://javascript.crockford.com/jsmin.html
|
||||
|
||||
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO |
||||
NOT CONTROL. |
||||
|
||||
This file adds these methods to JavaScript: |
||||
|
||||
object.toJSONString(whitelist) |
||||
This method produce a JSON text from a JavaScript value. |
||||
It must not contain any cyclical references. Illegal values |
||||
will be excluded. |
||||
|
||||
The default conversion for dates is to an ISO string. You can |
||||
add a toJSONString method to any date object to get a different |
||||
representation. |
||||
|
||||
The object and array methods can take an optional whitelist |
||||
argument. A whitelist is an array of strings. If it is provided, |
||||
keys in objects not found in the whitelist are excluded. |
||||
|
||||
string.parseJSON(filter) |
||||
This method parses a JSON text to produce an object or |
||||
array. It can throw a SyntaxError exception. |
||||
|
||||
The optional filter parameter is a function which can filter and |
||||
transform the results. It receives each of the keys and values, and |
||||
its return value is used instead of the original value. If it |
||||
returns what it received, then structure is not modified. If it |
||||
returns undefined then the member is deleted. |
||||
|
||||
Example: |
||||
|
||||
// Parse the text. If a key contains the string 'date' then
|
||||
// convert the value to a date.
|
||||
|
||||
myData = text.parseJSON(function (key, value) { |
||||
return key.indexOf('date') >= 0 ? new Date(value) : value; |
||||
}); |
||||
|
||||
This file will break programs with improper for..in loops. See |
||||
http://yuiblog.com/blog/2006/09/26/for-in-intrigue/
|
||||
|
||||
This file creates a global JSON object containing two methods: stringify |
||||
and parse. |
||||
|
||||
JSON.stringify(value, replacer, space) |
||||
value any JavaScript value, usually an object or array. |
||||
|
||||
replacer an optional parameter that determines how object |
||||
values are stringified for objects. It can be a |
||||
function or an array of strings. |
||||
|
||||
space an optional parameter that specifies the indentation |
||||
of nested structures. If it is omitted, the text will |
||||
be packed without extra whitespace. If it is a number, |
||||
it will specify the number of spaces to indent at each |
||||
level. If it is a string (such as '\t' or ' '), |
||||
it contains the characters used to indent at each level. |
||||
|
||||
This method produces a JSON text from a JavaScript value. |
||||
|
||||
When an object value is found, if the object contains a toJSON |
||||
method, its toJSON method will be called and the result will be |
||||
stringified. A toJSON method does not serialize: it returns the |
||||
value represented by the name/value pair that should be serialized, |
||||
or undefined if nothing should be serialized. The toJSON method |
||||
will be passed the key associated with the value, and this will be |
||||
bound to the object holding the key. |
||||
|
||||
For example, this would serialize Dates as ISO strings. |
||||
|
||||
Date.prototype.toJSON = function (key) { |
||||
function f(n) { |
||||
// Format integers to have at least two digits.
|
||||
return n < 10 ? '0' + n : n; |
||||
} |
||||
|
||||
return this.getUTCFullYear() + '-' + |
||||
f(this.getUTCMonth() + 1) + '-' + |
||||
f(this.getUTCDate()) + 'T' + |
||||
f(this.getUTCHours()) + ':' + |
||||
f(this.getUTCMinutes()) + ':' + |
||||
f(this.getUTCSeconds()) + 'Z'; |
||||
}; |
||||
|
||||
You can provide an optional replacer method. It will be passed the |
||||
key and value of each member, with this bound to the containing |
||||
object. The value that is returned from your method will be |
||||
serialized. If your method returns undefined, then the member will |
||||
be excluded from the serialization. |
||||
|
||||
If the replacer parameter is an array of strings, then it will be |
||||
used to select the members to be serialized. It filters the results |
||||
such that only members with keys listed in the replacer array are |
||||
stringified. |
||||
|
||||
Values that do not have JSON representations, such as undefined or |
||||
functions, will not be serialized. Such values in objects will be |
||||
dropped; in arrays they will be replaced with null. You can use |
||||
a replacer function to replace those with JSON values. |
||||
JSON.stringify(undefined) returns undefined. |
||||
|
||||
The optional space parameter produces a stringification of the |
||||
value that is filled with line breaks and indentation to make it |
||||
easier to read. |
||||
|
||||
If the space parameter is a non-empty string, then that string will |
||||
be used for indentation. If the space parameter is a number, then |
||||
the indentation will be that many spaces. |
||||
|
||||
Example: |
||||
|
||||
text = JSON.stringify(['e', {pluribus: 'unum'}]); |
||||
// text is '["e",{"pluribus":"unum"}]'
|
||||
|
||||
|
||||
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); |
||||
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
|
||||
|
||||
text = JSON.stringify([new Date()], function (key, value) { |
||||
return this[key] instanceof Date ? |
||||
'Date(' + this[key] + ')' : value; |
||||
}); |
||||
// text is '["Date(---current time---)"]'
|
||||
|
||||
|
||||
JSON.parse(text, reviver) |
||||
This method parses a JSON text to produce an object or array. |
||||
It can throw a SyntaxError exception. |
||||
|
||||
The optional reviver parameter is a function that can filter and |
||||
transform the results. It receives each of the keys and values, |
||||
and its return value is used instead of the original value. |
||||
If it returns what it received, then the structure is not modified. |
||||
If it returns undefined then the member is deleted. |
||||
|
||||
Example: |
||||
|
||||
// Parse the text. Values that look like ISO date strings will
|
||||
// be converted to Date objects.
|
||||
|
||||
myData = JSON.parse(text, function (key, value) { |
||||
var a; |
||||
if (typeof value === 'string') { |
||||
a = |
||||
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); |
||||
if (a) { |
||||
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], |
||||
+a[5], +a[6])); |
||||
} |
||||
} |
||||
return value; |
||||
}); |
||||
|
||||
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { |
||||
var d; |
||||
if (typeof value === 'string' && |
||||
value.slice(0, 5) === 'Date(' && |
||||
value.slice(-1) === ')') { |
||||
d = new Date(value.slice(5, -1)); |
||||
if (d) { |
||||
return d; |
||||
} |
||||
} |
||||
return value; |
||||
}); |
||||
|
||||
|
||||
This is a reference implementation. You are free to copy, modify, or |
||||
redistribute. |
||||
*/ |
||||
|
||||
/*jslint evil: true, regexp: true, unparam: true */ |
||||
|
||||
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, |
||||
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, |
||||
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, |
||||
lastIndex, length, parse, parseJSON, prototype, push, replace, slice, |
||||
stringify, test, toJSON, toJSONString, toString, valueOf |
||||
*/ |
||||
|
||||
|
||||
// Create a JSON object only if one does not already exist. We create the
|
||||
// methods in a closure to avoid creating global variables.
|
||||
|
||||
var JSON; |
||||
if (!JSON) { |
||||
JSON = {}; |
||||
} |
||||
|
||||
(function () { |
||||
'use strict'; |
||||
|
||||
function f(n) { |
||||
// Format integers to have at least two digits.
|
||||
return n < 10 ? '0' + n : n; |
||||
} |
||||
|
||||
if (typeof Date.prototype.toJSON !== 'function') { |
||||
|
||||
Date.prototype.toJSON = function (key) { |
||||
|
||||
return isFinite(this.valueOf()) ? |
||||
this.getUTCFullYear() + '-' + |
||||
f(this.getUTCMonth() + 1) + '-' + |
||||
f(this.getUTCDate()) + 'T' + |
||||
f(this.getUTCHours()) + ':' + |
||||
f(this.getUTCMinutes()) + ':' + |
||||
f(this.getUTCSeconds()) + 'Z' : null; |
||||
}; |
||||
|
||||
String.prototype.toJSON = |
||||
Number.prototype.toJSON = |
||||
Boolean.prototype.toJSON = function (key) { |
||||
return this.valueOf(); |
||||
}; |
||||
} |
||||
|
||||
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, |
||||
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, |
||||
gap, |
||||
indent, |
||||
meta = { // table of character substitutions
|
||||
'\b': '\\b', |
||||
'\t': '\\t', |
||||
'\n': '\\n', |
||||
'\f': '\\f', |
||||
'\r': '\\r', |
||||
'"' : '\\"', |
||||
'\\': '\\\\' |
||||
}, |
||||
rep; |
||||
|
||||
|
||||
function quote(string) { |
||||
|
||||
// If the string contains no control characters, no quote characters, and no
|
||||
// backslash characters, then we can safely slap some quotes around it.
|
||||
// Otherwise we must also replace the offending characters with safe escape
|
||||
// sequences.
|
||||
|
||||
escapable.lastIndex = 0; |
||||
return escapable.test(string) ? '"' + string.replace(escapable, function (a) { |
||||
var c = meta[a]; |
||||
return typeof c === 'string' ? c : |
||||
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); |
||||
}) + '"' : '"' + string + '"'; |
||||
} |
||||
|
||||
|
||||
function str(key, holder) { |
||||
|
||||
// Produce a string from holder[key].
|
||||
|
||||
var i, // The loop counter.
|
||||
k, // The member key.
|
||||
v, // The member value.
|
||||
length, |
||||
mind = gap, |
||||
partial, |
||||
value = holder[key]; |
||||
|
||||
// If the value has a toJSON method, call it to obtain a replacement value.
|
||||
|
||||
if (value && typeof value === 'object' && |
||||
typeof value.toJSON === 'function') { |
||||
value = value.toJSON(key); |
||||
} |
||||
|
||||
// If we were called with a replacer function, then call the replacer to
|
||||
// obtain a replacement value.
|
||||
|
||||
if (typeof rep === 'function') { |
||||
value = rep.call(holder, key, value); |
||||
} |
||||
|
||||
// What happens next depends on the value's type.
|
||||
|
||||
switch (typeof value) { |
||||
case 'string': |
||||
return quote(value); |
||||
|
||||
case 'number': |
||||
|
||||
// JSON numbers must be finite. Encode non-finite numbers as null.
|
||||
|
||||
return isFinite(value) ? String(value) : 'null'; |
||||
|
||||
case 'boolean': |
||||
case 'null': |
||||
|
||||
// If the value is a boolean or null, convert it to a string. Note:
|
||||
// typeof null does not produce 'null'. The case is included here in
|
||||
// the remote chance that this gets fixed someday.
|
||||
|
||||
return String(value); |
||||
|
||||
// If the type is 'object', we might be dealing with an object or an array or
|
||||
// null.
|
||||
|
||||
case 'object': |
||||
|
||||
// Due to a specification blunder in ECMAScript, typeof null is 'object',
|
||||
// so watch out for that case.
|
||||
|
||||
if (!value) { |
||||
return 'null'; |
||||
} |
||||
|
||||
// Make an array to hold the partial results of stringifying this object value.
|
||||
|
||||
gap += indent; |
||||
partial = []; |
||||
|
||||
// Is the value an array?
|
||||
|
||||
if (Object.prototype.toString.apply(value) === '[object Array]') { |
||||
|
||||
// The value is an array. Stringify every element. Use null as a placeholder
|
||||
// for non-JSON values.
|
||||
|
||||
length = value.length; |
||||
for (i = 0; i < length; i += 1) { |
||||
partial[i] = str(i, value) || 'null'; |
||||
} |
||||
|
||||
// Join all of the elements together, separated with commas, and wrap them in
|
||||
// brackets.
|
||||
|
||||
v = partial.length === 0 ? '[]' : gap ? |
||||
'[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : |
||||
'[' + partial.join(',') + ']'; |
||||
gap = mind; |
||||
return v; |
||||
} |
||||
|
||||
// If the replacer is an array, use it to select the members to be stringified.
|
||||
|
||||
if (rep && typeof rep === 'object') { |
||||
length = rep.length; |
||||
for (i = 0; i < length; i += 1) { |
||||
k = rep[i]; |
||||
if (typeof k === 'string') { |
||||
v = str(k, value); |
||||
if (v) { |
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v); |
||||
} |
||||
} |
||||
} |
||||
} else { |
||||
|
||||
// Otherwise, iterate through all of the keys in the object.
|
||||
|
||||
for (k in value) { |
||||
if (Object.prototype.hasOwnProperty.call(value, k)) { |
||||
v = str(k, value); |
||||
if (v) { |
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Join all of the member texts together, separated with commas,
|
||||
// and wrap them in braces.
|
||||
|
||||
v = partial.length === 0 ? '{}' : gap ? |
||||
'{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : |
||||
'{' + partial.join(',') + '}'; |
||||
gap = mind; |
||||
return v; |
||||
} |
||||
} |
||||
|
||||
// If the JSON object does not yet have a stringify method, give it one.
|
||||
|
||||
if (typeof JSON.stringify !== 'function') { |
||||
JSON.stringify = function (value, replacer, space) { |
||||
|
||||
// The stringify method takes a value and an optional replacer, and an optional
|
||||
// space parameter, and returns a JSON text. The replacer can be a function
|
||||
// that can replace values, or an array of strings that will select the keys.
|
||||
// A default replacer method can be provided. Use of the space parameter can
|
||||
// produce text that is more easily readable.
|
||||
|
||||
var i; |
||||
gap = ''; |
||||
indent = ''; |
||||
|
||||
// If the space parameter is a number, make an indent string containing that
|
||||
// many spaces.
|
||||
|
||||
if (typeof space === 'number') { |
||||
for (i = 0; i < space; i += 1) { |
||||
indent += ' '; |
||||
} |
||||
|
||||
// If the space parameter is a string, it will be used as the indent string.
|
||||
|
||||
} else if (typeof space === 'string') { |
||||
indent = space; |
||||
} |
||||
|
||||
// If there is a replacer, it must be a function or an array.
|
||||
// Otherwise, throw an error.
|
||||
|
||||
rep = replacer; |
||||
if (replacer && typeof replacer !== 'function' && |
||||
(typeof replacer !== 'object' || |
||||
typeof replacer.length !== 'number')) { |
||||
throw new Error('JSON.stringify'); |
||||
} |
||||
|
||||
// Make a fake root object containing our value under the key of ''.
|
||||
// Return the result of stringifying the value.
|
||||
|
||||
return str('', {'': value}); |
||||
}; |
||||
} |
||||
|
||||
|
||||
// If the JSON object does not yet have a parse method, give it one.
|
||||
|
||||
if (typeof JSON.parse !== 'function') { |
||||
JSON.parse = function (text, reviver) { |
||||
|
||||
// The parse method takes a text and an optional reviver function, and returns
|
||||
// a JavaScript value if the text is a valid JSON text.
|
||||
|
||||
var j; |
||||
|
||||
function walk(holder, key) { |
||||
|
||||
// The walk method is used to recursively walk the resulting structure so
|
||||
// that modifications can be made.
|
||||
|
||||
var k, v, value = holder[key]; |
||||
if (value && typeof value === 'object') { |
||||
for (k in value) { |
||||
if (Object.prototype.hasOwnProperty.call(value, k)) { |
||||
v = walk(value, k); |
||||
if (v !== undefined) { |
||||
value[k] = v; |
||||
} else { |
||||
delete value[k]; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return reviver.call(holder, key, value); |
||||
} |
||||
|
||||
|
||||
// Parsing happens in four stages. In the first stage, we replace certain
|
||||
// Unicode characters with escape sequences. JavaScript handles many characters
|
||||
// incorrectly, either silently deleting them, or treating them as line endings.
|
||||
|
||||
text = String(text); |
||||
cx.lastIndex = 0; |
||||
if (cx.test(text)) { |
||||
text = text.replace(cx, function (a) { |
||||
return '\\u' + |
||||
('0000' + a.charCodeAt(0).toString(16)).slice(-4); |
||||
}); |
||||
} |
||||
|
||||
// In the second stage, we run the text against regular expressions that look
|
||||
// for non-JSON patterns. We are especially concerned with '()' and 'new'
|
||||
// because they can cause invocation, and '=' because it can cause mutation.
|
||||
// But just to be safe, we want to reject all unexpected forms.
|
||||
|
||||
// We split the second stage into 4 regexp operations in order to work around
|
||||
// crippling inefficiencies in IE's and Safari's regexp engines. First we
|
||||
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
|
||||
// replace all simple value tokens with ']' characters. Third, we delete all
|
||||
// open brackets that follow a colon or comma or that begin the text. Finally,
|
||||
// we look to see that the remaining characters are only whitespace or ']' or
|
||||
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
|
||||
|
||||
if (/^[\],:{}\s]*$/ |
||||
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') |
||||
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') |
||||
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { |
||||
|
||||
// In the third stage we use the eval function to compile the text into a
|
||||
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
|
||||
// in JavaScript: it can begin a block or an object literal. We wrap the text
|
||||
// in parens to eliminate the ambiguity.
|
||||
|
||||
j = eval('(' + text + ')'); |
||||
|
||||
// In the optional fourth stage, we recursively walk the new structure, passing
|
||||
// each name/value pair to a reviver function for possible transformation.
|
||||
|
||||
return typeof reviver === 'function' ? |
||||
walk({'': j}, '') : j; |
||||
} |
||||
|
||||
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
||||
|
||||
throw new SyntaxError('JSON.parse'); |
||||
}; |
||||
} |
||||
|
||||
// Augment the basic prototypes if they have not already been augmented.
|
||||
// These forms are obsolete. It is recommended that JSON.stringify and
|
||||
// JSON.parse be used instead.
|
||||
|
||||
if (!Object.prototype.toJSONString) { |
||||
Object.prototype.toJSONString = function (filter) { |
||||
return JSON.stringify(this, filter); |
||||
}; |
||||
Object.prototype.parseJSON = function (filter) { |
||||
return JSON.parse(this, filter); |
||||
}; |
||||
} |
||||
}()); |
@ -1,87 +0,0 @@
|
||||
/* JSONPath 0.8.0 - XPath for JSON |
||||
* |
||||
* Copyright (c) 2007 Stefan Goessner (goessner.net) |
||||
* Licensed under the MIT (MIT-LICENSE.txt) licence. |
||||
*/ |
||||
function jsonPath(obj, expr, arg) { |
||||
var P = { |
||||
resultType: arg && arg.resultType || "VALUE", |
||||
result: [], |
||||
normalize: function(expr) { |
||||
var subx = []; |
||||
return expr.replace(/[\['](\??\(.*?\))[\]']/g, function($0,$1){return "[#"+(subx.push($1)-1)+"]";}) |
||||
.replace(/'?\.'?|\['?/g, ";") |
||||
.replace(/;;;|;;/g, ";..;") |
||||
.replace(/;$|'?\]|'$/g, "") |
||||
.replace(/#([0-9]+)/g, function($0,$1){return subx[$1];}); |
||||
}, |
||||
asPath: function(path) { |
||||
var x = path.split(";"), p = "$"; |
||||
for (var i=1,n=x.length; i<n; i++) |
||||
p += /^[0-9*]+$/.test(x[i]) ? ("["+x[i]+"]") : ("['"+x[i]+"']"); |
||||
return p; |
||||
}, |
||||
store: function(p, v) { |
||||
if (p) P.result[P.result.length] = P.resultType == "PATH" ? P.asPath(p) : v; |
||||
return !!p; |
||||
}, |
||||
trace: function(expr, val, path) { |
||||
if (expr) { |
||||
var x = expr.split(";"), loc = x.shift(); |
||||
x = x.join(";"); |
||||
if (val && val.hasOwnProperty(loc)) |
||||
P.trace(x, val[loc], path + ";" + loc); |
||||
else if (loc === "*") |
||||
P.walk(loc, x, val, path, function(m,l,x,v,p) { P.trace(m+";"+x,v,p); }); |
||||
else if (loc === "..") { |
||||
P.trace(x, val, path); |
||||
P.walk(loc, x, val, path, function(m,l,x,v,p) { typeof v[m] === "object" && P.trace("..;"+x,v[m],p+";"+m); }); |
||||
} |
||||
else if (/,/.test(loc)) { // [name1,name2,...]
|
||||
for (var s=loc.split(/'?,'?/),i=0,n=s.length; i<n; i++) |
||||
P.trace(s[i]+";"+x, val, path); |
||||
} |
||||
else if (/^\(.*?\)$/.test(loc)) // [(expr)]
|
||||
P.trace(P.eval(loc, val, path.substr(path.lastIndexOf(";")+1))+";"+x, val, path); |
||||
else if (/^\?\(.*?\)$/.test(loc)) // [?(expr)]
|
||||
P.walk(loc, x, val, path, function(m,l,x,v,p) { if (P.eval(l.replace(/^\?\((.*?)\)$/,"$1"),v[m],m)) P.trace(m+";"+x,v,p); }); |
||||
else if (/^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$/.test(loc)) // [start:end:step] phyton slice syntax
|
||||
P.slice(loc, x, val, path); |
||||
} |
||||
else |
||||
P.store(path, val); |
||||
}, |
||||
walk: function(loc, expr, val, path, f) { |
||||
if (val instanceof Array) { |
||||
for (var i=0,n=val.length; i<n; i++) |
||||
if (i in val) |
||||
f(i,loc,expr,val,path); |
||||
} |
||||
else if (typeof val === "object") { |
||||
for (var m in val) |
||||
if (val.hasOwnProperty(m)) |
||||
f(m,loc,expr,val,path); |
||||
} |
||||
}, |
||||
slice: function(loc, expr, val, path) { |
||||
if (val instanceof Array) { |
||||
var len=val.length, start=0, end=len, step=1; |
||||
loc.replace(/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/g, function($0,$1,$2,$3){start=parseInt($1||start);end=parseInt($2||end);step=parseInt($3||step);}); |
||||
start = (start < 0) ? Math.max(0,start+len) : Math.min(len,start); |
||||
end = (end < 0) ? Math.max(0,end+len) : Math.min(len,end); |
||||
for (var i=start; i<end; i+=step) |
||||
P.trace(i+";"+expr, val, path); |
||||
} |
||||
}, |
||||
eval: function(x, _v, _vname) { |
||||
try { return $ && _v && eval(x.replace(/@/g, "_v")); } |
||||
catch(e) { throw new SyntaxError("jsonPath: " + e.message + ": " + x.replace(/@/g, "_v").replace(/\^/g, "_a")); } |
||||
} |
||||
}; |
||||
|
||||
var $ = obj; |
||||
if (expr && obj && (P.resultType == "VALUE" || P.resultType == "PATH")) { |
||||
P.trace(P.normalize(expr).replace(/^\$;/,""), obj, "$"); |
||||
return P.result.length ? P.result : false; |
||||
} |
||||
}
|
@ -1,59 +0,0 @@
|
||||
<html> |
||||
<head> |
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script> |
||||
<script src="jsonpath-0.8.0.js"></script> |
||||
<script> |
||||
$(document).ready(function() { |
||||
window.doc = { "store": { |
||||
"book": [ |
||||
{ "category": "reference", |
||||
"author": "Nigel Rees", |
||||
"title": "Sayings of the Century", |
||||
"price": 8.95 |
||||
}, |
||||
{ "category": "fiction", |
||||
"author": "Evelyn Waugh", |
||||
"title": "Sword of Honour", |
||||
"price": 12.99 |
||||
}, |
||||
{ "category": "fiction", |
||||
"author": "Herman Melville", |
||||
"title": "Moby Dick", |
||||
"isbn": "0-553-21311-3", |
||||
"price": 8.99 |
||||
}, |
||||
{ "category": "fiction", |
||||
"author": "J. R. R. Tolkien", |
||||
"title": "The Lord of the Rings", |
||||
"isbn": "0-395-19395-8", |
||||
"price": 22.99 |
||||
} |
||||
], |
||||
"bicycle": { |
||||
"color": "red", |
||||
"price": 19.95, |
||||
"dot.notation": "new" |
||||
} |
||||
} |
||||
}; |
||||
|
||||
$('#src').append(JSON.stringify(window.doc, null, 4)); |
||||
|
||||
$('#btnEval').click(function(e) { |
||||
$('#result').empty(); |
||||
var path = $('#txtPath').attr('value'); |
||||
var res = jsonPath(window.doc, path); |
||||
$('#result').append("PATH : " + path + "<hr/>"); |
||||
$('#result').append(JSON.stringify(res, null, 4)); |
||||
}); |
||||
|
||||
|
||||
}); |
||||
</script> |
||||
</head> |
||||
<body> |
||||
<pre id="src"></pre> |
||||
<input id="txtPath" type="text" style="width:600px;" value="$.store.book[?(@.price<10)].title"><button id="btnEval">eval</button> |
||||
<pre id="result"></pre> |
||||
</body> |
||||
</html> |
Loading…
Reference in new issue