Browse Source

Remove a given path from json

pull/58/head
sbeimin 10 years ago
parent
commit
d3d0e85924
  1. 128
      json-path/src/main/java/com/jayway/jsonpath/JsonPath.java
  2. 10
      json-path/src/main/java/com/jayway/jsonpath/ReadContext.java
  3. 28
      json-path/src/main/java/com/jayway/jsonpath/internal/JsonReader.java
  4. 59
      json-path/src/test/java/com/jayway/jsonpath/RemoveTest.java

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

@ -15,20 +15,28 @@
package com.jayway.jsonpath; package com.jayway.jsonpath;
import com.jayway.jsonpath.internal.JsonReader; import static com.jayway.jsonpath.internal.Utils.isTrue;
import com.jayway.jsonpath.internal.Path; import static com.jayway.jsonpath.internal.Utils.notEmpty;
import com.jayway.jsonpath.internal.PathCompiler; import static com.jayway.jsonpath.internal.Utils.notNull;
import com.jayway.jsonpath.internal.Utils;
import com.jayway.jsonpath.spi.http.HttpProviderFactory;
import com.jayway.jsonpath.spi.json.JsonProvider;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.jayway.jsonpath.internal.Utils.*; import com.jayway.jsonpath.internal.EvaluationContext;
import com.jayway.jsonpath.internal.JsonReader;
import com.jayway.jsonpath.internal.Path;
import com.jayway.jsonpath.internal.PathCompiler;
import com.jayway.jsonpath.internal.Utils;
import com.jayway.jsonpath.spi.http.HttpProviderFactory;
import com.jayway.jsonpath.spi.json.JsonProvider;
/** /**
* <p/> * <p/>
@ -452,7 +460,58 @@ public class JsonPath {
return new JsonReader().parse(jsonInputStream).read(jsonPath, filters); return new JsonReader().parse(jsonInputStream).read(jsonPath, filters);
} }
//-------------------------
/**
* Creates a new JsonPath and applies it to the provided Json object
*
* @param json a json object
* @param jsonPath the json path
* @param filters filters to be applied to the filter place holders [?] in the path
* @return json object without elemens matched by given path
*/
@SuppressWarnings("rawtypes")
public static Map remove(Object json, String jsonPath, Predicate... filters) {
return parse(json).remove(jsonPath, Map.class, filters);
}
/**
* Creates a new JsonPath and applies it to the provided Json object
*
* @param json a json string
* @param jsonPath the json path
* @param filters filters to be applied to the filter place holders [?] in the path
* @return list of objects matched by the given path
*/
public static String remove(String json, String jsonPath, Predicate... filters) {
return parse(json).remove(jsonPath, String.class, filters);
}
/**
* Creates a new JsonPath and applies it to the provided Json object
*
* @param json url pointing to json doc
* @param jsonPath the json path
* @param filters filters to be applied to the filter place holders [?] in the path
* @return list of objects matched by the given path
*/
public static String remove(URL json, String jsonPath, Predicate... filters) throws IOException {
return parse(json).remove(jsonPath, String.class, filters);
}
/**
* Creates a new JsonPath and applies it to the provided Json object
*
* @param json json file
* @param jsonPath the json path
* @param filters filters to be applied to the filter place holders [?] in the path
* @return list of objects matched by the given path
*/
public static String remove(File json, String jsonPath, Predicate... filters) throws IOException {
return parse(json).remove(jsonPath, String.class, filters);
}
// -------------------------------------------------------- // --------------------------------------------------------
// //
// Static Fluent API // Static Fluent API
@ -589,4 +648,59 @@ public class JsonPath {
public static ReadContext parse(URL json, Configuration configuration) throws IOException { public static ReadContext parse(URL json, Configuration configuration) throws IOException {
return new JsonReader(configuration).parse(json); return new JsonReader(configuration).parse(json);
} }
private List<String> splitPath(String pathSteps) {
List<String> result = new ArrayList<String>();
for (String string : pathSteps.split("\\]"))
result.add(string.replaceAll("[\\[\\$\\']+", ""));
return result;
}
/**
* Applies this JsonPath to the provided json document.
* Note that the document must be identified as either a List or Map by
* the {@link JsonProvider}
*
* @param jsonObject a container Object
* @param configuration configuration to use
* @param Class<T> expected return type
* @return json object without elemens matched by the path
*/
@SuppressWarnings("unchecked")
public <T> T removeTyped(Object jsonObject, Configuration configuration, Class<T> returnType) {
boolean optSuppressExceptions = configuration.containsOption(Option.SUPPRESS_EXCEPTIONS);
Object result = jsonObject;
try {
EvaluationContext evalContext = path.evaluate(jsonObject, jsonObject, configuration);
for (String pathSteps : evalContext.getPathList())
result = remove(result, splitPath(pathSteps));
} catch (RuntimeException e){
if(!optSuppressExceptions){
throw e;
}
}
if(Map.class.isAssignableFrom(returnType))
return (T) result;
if(String.class.isAssignableFrom(returnType))
return (T) configuration.jsonProvider().toJson(result);
throw new RuntimeException("Unknown returnType: "+returnType.getSimpleName());
}
@SuppressWarnings("unchecked")
private <T> T remove(T jsonObject, List<String> pathList) {
if(jsonObject instanceof Map) {
Map<String, Object> map = (Map<String, Object>) jsonObject;
Set<String> keys = new HashSet<String>(map.keySet());
for (String key : keys) {
if(key.equals(pathList.get(0))) {
if(pathList.size() > 1)
remove(map.get(key), pathList.subList(1, pathList.size()));
else
map.remove(key);
}
}
return (T) map;
}
return jsonObject;
}
} }

10
json-path/src/main/java/com/jayway/jsonpath/ReadContext.java

@ -14,6 +14,7 @@
*/ */
package com.jayway.jsonpath; package com.jayway.jsonpath;
public interface ReadContext { public interface ReadContext {
/** /**
@ -84,4 +85,13 @@ public interface ReadContext {
*/ */
ReadContext withListeners(EvaluationListener... listener); ReadContext withListeners(EvaluationListener... listener);
/**
* Removes the given path from this context
*
* @param path path to read
* @param filters filters
* @param <T>
* @return result
*/
<T> T remove(String jsonPath, Class<T> returnType, Predicate... filters);
} }

28
json-path/src/main/java/com/jayway/jsonpath/internal/JsonReader.java

@ -14,13 +14,8 @@
*/ */
package com.jayway.jsonpath.internal; package com.jayway.jsonpath.internal;
import com.jayway.jsonpath.Configuration; import static com.jayway.jsonpath.internal.Utils.notEmpty;
import com.jayway.jsonpath.EvaluationListener; import static com.jayway.jsonpath.internal.Utils.notNull;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.ParseContext;
import com.jayway.jsonpath.Predicate;
import com.jayway.jsonpath.ReadContext;
import com.jayway.jsonpath.spi.http.HttpProviderFactory;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -28,8 +23,13 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import static com.jayway.jsonpath.internal.Utils.notEmpty; import com.jayway.jsonpath.Configuration;
import static com.jayway.jsonpath.internal.Utils.notNull; import com.jayway.jsonpath.EvaluationListener;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.ParseContext;
import com.jayway.jsonpath.Predicate;
import com.jayway.jsonpath.ReadContext;
import com.jayway.jsonpath.spi.http.HttpProviderFactory;
public class JsonReader implements ParseContext, ReadContext { public class JsonReader implements ParseContext, ReadContext {
@ -158,6 +158,16 @@ public class JsonReader implements ParseContext, ReadContext {
return configuration.mappingProvider().map(obj, targetType, configuration); return configuration.mappingProvider().map(obj, targetType, configuration);
} }
@Override
public <T> T remove(String path, Class<T> returnType, Predicate... filters) {
notEmpty(path, "path can not be null or empty");
return remove(JsonPath.compile(path, filters), returnType);
}
public <T> T remove(JsonPath path, Class<T> returnType) {
notNull(path, "path can not be null");
return path.removeTyped(json, configuration, returnType);
}
private final class LimitingEvaluationListener implements EvaluationListener { private final class LimitingEvaluationListener implements EvaluationListener {

59
json-path/src/test/java/com/jayway/jsonpath/RemoveTest.java

@ -0,0 +1,59 @@
package com.jayway.jsonpath;
import static com.jayway.jsonpath.JsonPath.using;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
public class RemoveTest extends BaseTest {
@Test
public void fromJsonString() {
String result = JsonPath.remove("{\"val\":1,\"val2\":2}", "$.val");
assertThat(result).isEqualTo("{\"val2\":2}");
}
@SuppressWarnings("unchecked")
@Test
public void fromMap() {
Map<String, Object> model = new HashMap<String, Object>(){{
put("a", "a-val");
put("b", "b-val");
put("c", "c-val");
}};
Configuration conf = Configuration.defaultConfiguration();
assertThat(using(conf).parse(model).remove("$.b", Map.class))
.containsEntry("a", "a-val")
.containsEntry("c", "c-val").doesNotContainKey("b");
}
@Test
public void fromMapToString() {
Map<String, Object> model = new HashMap<String, Object>(){{
put("a", "a-val");
put("b", "b-val");
put("c", "c-val");
}};
Configuration conf = Configuration.defaultConfiguration();
assertThat(using(conf).parse(model).remove("$.b", String.class))
.contains("\"a\":\"a-val\"")
.contains("\"c\":\"c-val\"")
.doesNotContain("\"b\":\"b-val\"");
}
@SuppressWarnings("unchecked")
@Test
public void fromStringToMap() {
Configuration conf = Configuration.defaultConfiguration();
assertThat(using(conf).parse("{\"val\":1,\"val2\":2}").remove("$.val2", Map.class))
.containsEntry("val", 1).doesNotContainKey("val2");
}
}
Loading…
Cancel
Save