diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/path/EvaluationContextImpl.java b/json-path/src/main/java/com/jayway/jsonpath/internal/path/EvaluationContextImpl.java index 0d35c9dd..d3fd0b1c 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/path/EvaluationContextImpl.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/path/EvaluationContextImpl.java @@ -52,6 +52,10 @@ public class EvaluationContextImpl implements EvaluationContext { private int resultIndex = 0; + public RootPathToken getRoot(){ + return ((CompiledPath) path).getRoot(); + } + public EvaluationContextImpl(Path path, Object rootDocument, Configuration configuration, boolean forUpdate) { notNull(path, "path can not be null"); notNull(rootDocument, "root can not be null"); diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathToken.java b/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathToken.java index 69e0b8ba..34cf1402 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathToken.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathToken.java @@ -29,6 +29,12 @@ public abstract class PathToken { private PathToken next; private Boolean definite = null; private Boolean upstreamDefinite = null; + private int upstreamArrayIndex = -1; + + + public void setUpstreamArrayIndex(int idx){ + upstreamArrayIndex = idx; + } PathToken appendTailToken(PathToken next) { this.next = next; @@ -75,7 +81,10 @@ public abstract class PathToken { } PathRef pathRef = ctx.forUpdate() ? PathRef.create(model, property) : PathRef.NO_OP; if (isLeaf()) { - ctx.addResult(evalPath, pathRef, propertyVal); + String idx = "[" + String.valueOf(upstreamArrayIndex) + "]"; + if(idx.equals("[-1]") || ctx.getRoot().getTail().prev().getPathFragment().equals(idx)){ + ctx.addResult(evalPath, pathRef, propertyVal); + } } else { next().evaluate(evalPath, pathRef, propertyVal, ctx); diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/path/RootPathToken.java b/json-path/src/main/java/com/jayway/jsonpath/internal/path/RootPathToken.java index 2d443ec1..1a786ac6 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/path/RootPathToken.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/path/RootPathToken.java @@ -32,6 +32,10 @@ public class RootPathToken extends PathToken { this.tokenCount = 1; } + public PathToken getTail(){ + return this.tail; + } + @Override public int getTokenCount() { return tokenCount; diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/path/ScanPathToken.java b/json-path/src/main/java/com/jayway/jsonpath/internal/path/ScanPathToken.java index f98c3729..9d6da973 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/path/ScanPathToken.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/path/ScanPathToken.java @@ -55,6 +55,7 @@ public class ScanPathToken extends PathToken { int idx = 0; for (Object evalModel : models) { String evalPath = currentPath + "[" + idx + "]"; + next.setUpstreamArrayIndex(idx); next.evaluate(evalPath, parent, evalModel, ctx); idx++; } diff --git a/json-path/src/test/java/com/jayway/jsonpath/internal/function/Issue273.java b/json-path/src/test/java/com/jayway/jsonpath/internal/function/Issue273.java new file mode 100644 index 00000000..cbf1752e --- /dev/null +++ b/json-path/src/test/java/com/jayway/jsonpath/internal/function/Issue273.java @@ -0,0 +1,95 @@ +package com.jayway.jsonpath.internal.function; + +import net.minidev.json.JSONArray; +import com.jayway.jsonpath.JsonPath; +import org.junit.Test; + + +import static org.junit.Assert.assertEquals; + +public class Issue273 { + @Test + public void testGetPropertyFromArray(){ + String json = "[\n" + + " [\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\" : \"Herman Melville\",\n" + + " \"title\" : \"Moby Dick\",\n" + + " \"isbn\" : \"0-553-21311-3\",\n" + + " \"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" + + " \"price\" : 22.99\n" + + " }\n" + + " ],\n" + + " {\n" + + " \"color\" : \"red\",\n" + + " \"price\" : 19.95\n" + + " }\n" + + "]\n"; + + JSONArray arr = JsonPath.read(json,"$..[2].author"); + assertEquals(arr.get(0), "Herman Melville"); + } + + @Test + public void testGetPropertyFromObject(){ + String json = "{\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\": \"Herman Melville\",\n" + + " \"title\": \"Moby Dick\",\n" + + " \"isbn\": \"0-553-21311-3\",\n" + + " \"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" + + " \"price\": 22.99\n" + + " }\n" + + " ],\n" + + " \"bicycle\": {\n" + + " \"color\": \"red\",\n" + + " \"price\": 19.95\n" + + " }\n" + + " },\n" + + " \"expensive\": 10\n" + + "}\n" + + " "; + JSONArray arr = JsonPath.read(json,"$..[2].author"); + assertEquals(arr.get(0), "Herman Melville"); + } +}