Browse Source

Option handling improved.

pull/41/head
Kalle Stenflo 11 years ago
parent
commit
8da4d1a1d6
  1. 4
      json-path-web-test/src/main/resources/css/font-awesome.min.css
  2. 34
      json-path-web-test/src/main/resources/html/index.html
  3. 2
      json-path-web-test/src/main/resources/js/prettify.js
  4. 4
      json-path/src/main/java/com/jayway/jsonpath/Criteria.java
  5. 37
      json-path/src/main/java/com/jayway/jsonpath/JsonPath.java
  6. 53
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/compiler/EvaluationContextImpl.java
  7. 5
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/compiler/PathCompiler.java
  8. 50
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/compiler/PathToken.java
  9. 14
      json-path/src/main/java/com/jayway/jsonpath/spi/compiler/EvaluationContext.java
  10. 4
      json-path/src/test/java/com/jayway/jsonpath/FilterTest.java
  11. 4
      json-path/src/test/java/com/jayway/jsonpath/IssuesTest.java
  12. 4
      json-path/src/test/java/com/jayway/jsonpath/JsonPathFilterTest.java
  13. 6
      json-path/src/test/java/com/jayway/jsonpath/internal/TestInternal3.java
  14. 2
      json-path/src/test/java/com/jayway/jsonpath/reader/ReadConfigurationTest.java

4
json-path-web-test/src/main/resources/css/font-awesome.min.css vendored

File diff suppressed because one or more lines are too long

34
json-path-web-test/src/main/resources/html/index.html

@ -4,9 +4,9 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>JSONPath evaluator</title>
<link href="//netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">
<link rel="stylesheet" href="/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/prettify.css">
<link rel="stylesheet" href="/css/font-awesome.min.css">
<script type="text/javascript" src="/js/prettify.js"></script>
<script type="text/javascript" src="/js/jquery.min.js"></script>
@ -21,9 +21,9 @@
<div class="form-group">
<select id="selTemplates" name="template" class="form-control">
<option value="blank"></option>
<option value="goessner.json">goessner</option>
<option value="twitter.json">twitter</option>
<option value="webxml.json">webapp</option>
<option value="goessner.json">Goessner examle</option>
<option value="twitter.json">Twitter API</option>
<option value="webxml.json">Webapp</option>
<option value="20k.json">20k</option>
</select>
</div>
@ -33,7 +33,7 @@
</div>
<div class="input-group">
<span id="path-status-tool" class="input-group-addon" data-toggle="tooltip" data-placement="top" title="Invalid path"><span id="path-status" class="glyphicon glyphicon-ban-circle"></span></span>
<span id="path-status-tool" class="input-group-addon" data-toggle="tooltip" data-placement="top" title="Invalid path"><span id="path-status" class="fa fa-ban"></span></span>
<input id="txtPath" name="path" placeholder="Enter path" autocomplete="off" class="form-control"/>
<span class="input-group-btn">
<button id="submit" class="btn btn-primary" type="button">Go!</button>
@ -45,7 +45,7 @@
<div class="row">
<div class="col-md-6">
<fieldset>
<legend>Result options</legend>
<legend>JSONPath options</legend>
<div class="radio">
<label>
<input type="radio" name="rbType" value="VALUE" checked/>
@ -66,20 +66,20 @@
<legend>Jayway options</legend>
<div class="checkbox">
<label>
<input type="checkbox" name="flagWrap" id="cbFlagWrap" />
Always return result as list
<input type="checkbox" name="flagSuppress" id="cbFlagSuppress" />
Suppress exceptions
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="flagMerge" id="cbFlagMerge" />
Merge multi props to new object
<input type="checkbox" name="flagWrap" id="cbFlagWrap" />
Always return result list
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="flagSuppress" id="cbFlagSuppress" />
Suppress exceptions
<input type="checkbox" name="flagMerge" id="cbFlagMerge" />
Merge multi props to new object
</label>
</div>
</fieldset>
@ -185,25 +185,25 @@
var pathString = $("#txtPath").val();
var updateDisplay = function(icon, tooltip){
$('#path-status').removeClass().addClass('glyphicon ' + icon);
$('#path-status').removeClass().addClass('fa ' + icon);
$('#path-status-tool').attr('data-original-title', tooltip).tooltip('fixTitle');
};
if(pathString.length ==0){
updateDisplay('glyphicon-ban-circle', 'Invalid path');
updateDisplay('fa-ban', 'Invalid path');
return;
}
$.get('/api/validate/?path=' + pathString, function(data) {
if(data){
if(data.result === -1){
updateDisplay('glyphicon-ban-circle', 'Invalid path');
updateDisplay('fa-ban', 'Invalid path');
}
else if(data.result === 0){
updateDisplay('glyphicon-record', 'Path is definite');
updateDisplay('fa-bullseye', 'Path is definite');
}
else if(data.result === 1){
updateDisplay('glyphicon-align-justify', 'Path is indefinite');
updateDisplay('fa-navicon', 'Path is indefinite');
}
}
});

2
json-path-web-test/src/main/resources/js/prettify.js

@ -16,7 +16,7 @@
a.a=b;a.d=g.d;a.e=0;I(d,b)(a);var s=/\bMSIE\s(\d+)/.exec(navigator.userAgent),s=s&&+s[1]<=8,d=/\n/g,x=a.a,m=x.length,g=0,j=a.d,k=j.length,b=0,c=a.g,i=c.length,r=0;c[i]=m;var n,e;for(e=n=0;e<i;)c[e]!==c[e+2]?(c[n++]=c[e++],c[n++]=c[e++]):e+=2;i=n;for(e=n=0;e<i;){for(var p=c[e],w=c[e+1],t=e+2;t+2<=i&&c[t+1]===w;)t+=2;c[n++]=p;c[n++]=w;e=t}c.length=n;var f=a.c,h;if(f)h=f.style.display,f.style.display="none";try{for(;b<k;){var l=j[b+2]||m,B=c[r+2]||m,t=Math.min(l,B),A=j[b+1],G;if(A.nodeType!==1&&(G=x.substring(g,
t))){s&&(G=G.replace(d,"\r"));A.nodeValue=G;var L=A.ownerDocument,o=L.createElement("span");o.className=c[r+1];var v=A.parentNode;v.replaceChild(o,A);o.appendChild(A);g<l&&(j[b+1]=A=L.createTextNode(x.substring(t,l)),v.insertBefore(A,o.nextSibling))}g=t;g>=l&&(b+=2);g>=B&&(r+=2)}}finally{if(f)f.style.display=h}}catch(u){D.console&&console.log(u&&u.stack||u)}}var D=window,y=["break,continue,do,else,for,if,return,while"],E=[[y,"auto,case,char,const,default,double,enum,extern,float,goto,inline,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],M=[E,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,delegate,dynamic_cast,explicit,export,friend,generic,late_check,mutable,namespace,nullptr,property,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],N=[E,"abstract,assert,boolean,byte,extends,final,finally,implements,import,instanceof,interface,null,native,package,strictfp,super,synchronized,throws,transient"],
O=[N,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,internal,into,is,let,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var,virtual,where"],E=[E,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],P=[y,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
O=[N,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,internal,into,is,let,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var,virtual,where"],E=[E,"debugger,eval,export,function,getValue,null,set,undefined,var,with,Infinity,NaN"],P=[y,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
Q=[y,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],W=[y,"as,assert,const,copy,drop,enum,extern,fail,false,fn,impl,let,log,loop,match,mod,move,mut,priv,pub,pure,ref,self,static,struct,true,trait,type,unsafe,use"],y=[y,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],R=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/,
V=/\S/,X=v({keywords:[M,O,E,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",P,Q,y],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),F={};p(X,["default-code"]);p(C([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",
/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);p(C([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],

4
json-path/src/main/java/com/jayway/jsonpath/Criteria.java

@ -272,7 +272,7 @@ public class Criteria implements Predicate {
if (CriteriaType.EXISTS == criteriaType) {
boolean exists = ((Boolean) expected);
try {
path.evaluate(model, configuration.options(Option.THROW_ON_MISSING_PROPERTY)).get();
path.evaluate(model, configuration.options(Option.THROW_ON_MISSING_PROPERTY)).getValue();
return exists == true;
} catch (PathNotFoundException e) {
return exists == false;
@ -280,7 +280,7 @@ public class Criteria implements Predicate {
} else {
try {
final Object actual = path.evaluate(model, configuration).get();
final Object actual = path.evaluate(model, configuration).getValue();
return criteriaType.eval(expected, actual, configuration);
} catch (CompareException e) {
return false;

37
json-path/src/main/java/com/jayway/jsonpath/JsonPath.java

@ -172,29 +172,36 @@ public class JsonPath {
boolean optSuppressExceptions = configuration.getOptions().contains(Option.SUPPRESS_EXCEPTIONS);
boolean optThrowOnMissingProperty = configuration.getOptions().contains(Option.THROW_ON_MISSING_PROPERTY);
Object result = null;
try {
result = path.evaluate(jsonObject, configuration).getWithOptions();
if(optAsPathList){
return (T)path.evaluate(jsonObject, configuration).getPath();
} else {
Object res = path.evaluate(jsonObject, configuration).getValue();
if(optAlwaysReturnList && path.isDefinite()){
Object array = configuration.getProvider().createArray();
configuration.getProvider().setProperty(array, 0, res);
return (T)array;
} else {
return (T)res;
}
}
} catch (RuntimeException e){
if(optThrowOnMissingProperty || (!optThrowOnMissingProperty && !optSuppressExceptions)){
if(optThrowOnMissingProperty || !optSuppressExceptions){
throw e;
}
}
if(optAsPathList){
return (T)configuration.getProvider().createArray();
} else {
if(optAlwaysReturnList){
return (T)configuration.getProvider().createArray();
} else {
if(optSuppressExceptions){
if(path.isDefinite() && !optAlwaysReturnList && !optAsPathList){
result = null;
} else {
result = configuration.getProvider().createArray();
}
}
return (T)(path.isDefinite() ? null : configuration.getProvider().createArray());
}
}
return (T)result;
}
/*
public <T> T read(Object jsonObject, Configuration configuration) {
return (T)path.evaluate(jsonObject, configuration).getWithOptions();
}*/
/**
* Applies this JsonPath to the provided json string

53
json-path/src/main/java/com/jayway/jsonpath/internal/spi/compiler/EvaluationContextImpl.java

@ -2,11 +2,13 @@ package com.jayway.jsonpath.internal.spi.compiler;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.PathNotFoundException;
import com.jayway.jsonpath.spi.compiler.EvaluationContext;
import com.jayway.jsonpath.spi.compiler.Path;
import com.jayway.jsonpath.spi.json.JsonProvider;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@ -16,22 +18,21 @@ import java.util.Set;
class EvaluationContextImpl implements EvaluationContext {
private final Configuration configuration;
private final Object objectResult;
private final List<String> pathResult;
private final Object valueResult;
private final Object pathResult;
private final Path path;
private int resultIndex = 0;
EvaluationContextImpl(Path path, Configuration configuration) {
this.path = path;
this.configuration = configuration;
this.objectResult = configuration.getProvider().createArray();
this.pathResult = new ArrayList<String>();
this.valueResult = configuration.getProvider().createArray();
this.pathResult = configuration.getProvider().createArray();
}
void addResult(String path, Object model) {
pathResult.add(path);
configuration.getProvider().setProperty(objectResult, resultIndex, model);
configuration.getProvider().setProperty(valueResult, resultIndex, model);
configuration.getProvider().setProperty(pathResult, resultIndex, path);
resultIndex++;
}
@ -50,36 +51,34 @@ class EvaluationContextImpl implements EvaluationContext {
@Override
public <T> T get() {
public <T> T getValue() {
if (path.isDefinite()) {
return (T) jsonProvider().getArrayIndex(objectResult, 0);
if(resultIndex == 0){
throw new PathNotFoundException("No results for path: " + path.toString());
}
return (T) jsonProvider().getArrayIndex(valueResult, 0);
}
return (T) objectResult;
return (T) valueResult;
}
@Override
public Object getWithOptions() {
boolean optAsPathList = configuration.getOptions().contains(Option.AS_PATH_LIST);
boolean optAlwaysReturnList = configuration.getOptions().contains(Option.ALWAYS_RETURN_LIST);
if (optAsPathList) {
Object array = configuration.getProvider().createArray();
int i = 0;
for (String p : pathResult) {
configuration.getProvider().setProperty(array, i, p);
i++;
}
return array;
} else if (optAlwaysReturnList) {
return objectResult;
} else {
return get();
public <T> T getPath() {
if(resultIndex == 0){
throw new PathNotFoundException("No results for path: " + path.toString());
}
return (T)pathResult;
}
@Override
public List<String> getPathList() {
return pathResult;
List<String> res = new ArrayList<String>();
if(resultIndex > 0){
Iterable<Object> objects = configuration.getProvider().toIterable(pathResult);
for (Object o : objects) {
res.add((String)o);
}
}
return res;
}
}

5
json-path/src/main/java/com/jayway/jsonpath/internal/spi/compiler/PathCompiler.java

@ -28,6 +28,7 @@ public class PathCompiler {
private static final char PERIOD = '.';
private static final char BRACKET_OPEN = '[';
private static final char BRACKET_CLOSE = ']';
private static final char SPACE = ' ';
private static final Cache cache = new Cache(200);
@ -60,6 +61,8 @@ public class PathCompiler {
char current = chars[i];
switch (current) {
case SPACE:
throw new InvalidPathException("Space not allowed in path");
case DOCUMENT:
fragment = "$";
i++;
@ -132,7 +135,7 @@ public class PathCompiler {
int skipCount = 0;
while (index < chars.length) {
char current = chars[index];
if (current == PERIOD || current == BRACKET_OPEN) {
if (current == PERIOD || current == BRACKET_OPEN || current == SPACE) {
break;
}
index++;

50
json-path/src/main/java/com/jayway/jsonpath/internal/spi/compiler/PathToken.java

@ -24,39 +24,41 @@ abstract class PathToken {
String property = properties.get(0);
String evalPath = currentPath + "['" + property + "']";
Object propertyVal = readObjectProperty(property, model, ctx);
if(propertyVal == JsonProvider.UNDEFINED){
return;
}
if (isLeaf()) {
ctx.addResult(evalPath, propertyVal);
} else {
next().evaluate(evalPath, propertyVal, ctx);
}
} else {
if(ctx.configuration().getOptions().contains(Option.MERGE_MULTI_PROPS)) {
String evalPath = currentPath + "[" + Utils.join(", ", "'", properties) + "]";
String evalPath = currentPath + "[" + Utils.join(", ", "'", properties) + "]";
if (!isLeaf()) {
throw new InvalidPathException("Multi properties can only be used as path leafs: " + evalPath);
} else {
Object map = ctx.jsonProvider().createMap();
for (String property : properties) {
if(hasProperty(property, model, ctx)) {
Object propertyVal = readObjectProperty(property, model, ctx);
ctx.jsonProvider().setProperty(map, property, propertyVal);
}
if (!isLeaf()) {
throw new InvalidPathException("Multi properties can only be used as path leafs: " + evalPath);
}
if(ctx.configuration().getOptions().contains(Option.MERGE_MULTI_PROPS)) {
Object map = ctx.jsonProvider().createMap();
for (String property : properties) {
Object propertyVal = readObjectProperty(property, model, ctx);
if(propertyVal == JsonProvider.UNDEFINED){
continue;
}
ctx.addResult(evalPath, map);
ctx.jsonProvider().setProperty(map, property, propertyVal);
}
ctx.addResult(evalPath, map);
} else {
if (!isLeaf()) {
String evalPath = currentPath + "[" + Utils.join(", ", "'", properties) + "]";
throw new InvalidPathException("Multi properties can only be used as path leafs: " + evalPath);
} else {
for (String property : properties) {
String evalPath = currentPath + "['" + property + "']";
if(hasProperty(property, model, ctx)) {
Object propertyVal = readObjectProperty(property, model, ctx);
ctx.addResult(evalPath, propertyVal);
for (String property : properties) {
evalPath = currentPath + "['" + property + "']";
if(hasProperty(property, model, ctx)) {
Object propertyVal = readObjectProperty(property, model, ctx);
if(propertyVal == JsonProvider.UNDEFINED){
continue;
}
ctx.addResult(evalPath, propertyVal);
}
}
}
@ -68,9 +70,11 @@ abstract class PathToken {
}
private Object readObjectProperty(String property, Object model, EvaluationContextImpl ctx) {
Object val = ctx.jsonProvider().getMapValue(model, property, ctx.options().contains(Option.THROW_ON_MISSING_PROPERTY));
Object val = ctx.jsonProvider().getMapValue(model, property, true);
if(val == JsonProvider.UNDEFINED){
throw new PathNotFoundException("Property ['" + property + "'] not found in the current context" );
if(ctx.options().contains(Option.THROW_ON_MISSING_PROPERTY)) {
throw new PathNotFoundException("Property ['" + property + "'] not found in the current context");
}
}
return val;
}

14
json-path/src/main/java/com/jayway/jsonpath/spi/compiler/EvaluationContext.java

@ -19,17 +19,11 @@ public interface EvaluationContext {
* @param <T> expected return type
* @return evaluation result
*/
<T> T get();
<T> T getValue();
<T> T getPath();
/**
* This method does adhere to configuration settings like
*
* {@link com.jayway.jsonpath.Option#ALWAYS_RETURN_LIST}
* {@link com.jayway.jsonpath.Option#AS_PATH_LIST}
*
* @return evaluation result
*/
Object getWithOptions();
/**
* Convenience method to get list of hits as String path representations

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

@ -392,7 +392,7 @@ public class FilterTest {
Filter customFilter = new Filter.FilterAdapter<Map<String, Object>>() {
@Override
public boolean apply(check, confMap<String, Object> map) {
if (map.get("name").equals("rootGrandChild_A")) {
if (map.getValue("name").equals("rootGrandChild_A")) {
return true;
}
return false;
@ -427,7 +427,7 @@ public class FilterTest {
List<Integer> res = JsonPath.read(doc, "$.items[?]", customFilter);
assertEquals(1, res.get(0).intValue());
assertEquals(1, res.getValue(0).intValue());
*/
}

4
json-path/src/test/java/com/jayway/jsonpath/IssuesTest.java

@ -141,8 +141,8 @@ public class IssuesTest {
System.out.println(result);
//assertThat(result.get(0), is(new Double(10.1)));
//assertThat(result.get(1), is(new Double(21.0)));
//assertThat(result.getValue(0), is(new Double(10.1)));
//assertThat(result.getValue(1), is(new Double(21.0)));
}

4
json-path/src/test/java/com/jayway/jsonpath/JsonPathFilterTest.java

@ -73,7 +73,7 @@ public class JsonPathFilterTest {
Filter customFilter = new Filter.FilterAdapter<Map<String, Object>>() {
@Override
public boolean accept(Map<String, Object> map) {
if(map.get("name").equals("rootGrandChild_A")){
if(map.getValue("name").equals("rootGrandChild_A")){
return true;
}
return false;
@ -109,7 +109,7 @@ public class JsonPathFilterTest {
List<Integer> res = JsonPath.read(doc, "$.items[?]", customFilter);
assertEquals(1, res.get(0).intValue());
assertEquals(1, res.getValue(0).intValue());
}
*/

6
json-path/src/test/java/com/jayway/jsonpath/internal/TestInternal3.java

@ -29,7 +29,7 @@ public class TestInternal3 extends TestBase {
@Test
public void a_root_object_can_be_evaluated() {
Map<String, Object> result = tokenize("$").evaluate(DOC, CONF).get();
Map<String, Object> result = tokenize("$").evaluate(DOC, CONF).getValue();
assertThat(result)
.containsKey("store")
@ -39,7 +39,7 @@ public class TestInternal3 extends TestBase {
@Test
public void a_definite_array_item_property_can_be_evaluated() {
String result = tokenize("$.store.book[0].author").evaluate(DOC, CONF).get();
String result = tokenize("$.store.book[0].author").evaluate(DOC, CONF).getValue();
assertThat(result).isEqualTo("Nigel Rees");
}
@ -47,7 +47,7 @@ public class TestInternal3 extends TestBase {
@Test
public void a_wildcard_array_item_property_can_be_evaluated() {
List result = tokenize("$.store.book[*].author").evaluate(DOC, CONF).get();
List result = tokenize("$.store.book[*].author").evaluate(DOC, CONF).getValue();
assertThat(result).containsOnly(
"Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien");

2
json-path/src/test/java/com/jayway/jsonpath/reader/ReadConfigurationTest.java

@ -34,7 +34,7 @@ public class ReadConfigurationTest {
Object updatedJsonModel = JsonPath.parse("{...}")
.write("$['store'][1]['name']", "new name")
.write("$.store[1].age", 43)
.get();
.getValue();
*/
}

Loading…
Cancel
Save