New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] JSONPath.set not working for array filter expressions #1469
Comments
https://oss.sonatype.org/content/repositories/snapshots/com/alibaba/fastjson2/fastjson2/2.0.32-SNAPSHOT/ public class Issue1469 {
@Test
public void test() {
JSONObject posts = JSON.parseObject(STR);
JSONPath jsonPath = JSONPath.of("$.posts[?(@.id == 1)]");
jsonPath.setCallback(posts, e -> {
JSONObject object = ((JSONObject) e).clone();
object.put("title", "XXX");
return object;
});
assertEquals(
"{\"posts\":[{\"id\":1,\"title\":\"XXX\"},{\"id\":2,\"title\":\"DEF\"}]}",
posts.toJSONString()
);
}
static final String STR = "{\n" +
" \"posts\": [\n" +
" {\n" +
" \"id\": 1,\n" +
" \"title\": \"ABC\"\n" +
" },\n" +
" {\n" +
" \"id\": 2,\n" +
" \"title\": \"DEF\"\n" +
" }\n" +
" ]\n" +
"}";
} |
Thanks @wenshao, I see We basically try to achieve the opposite of |
setCallback support BiFunction, such as : @Test
public void test1() {
JSONObject posts = JSON.parseObject(STR);
JSONPath jsonPath = JSONPath.of("$.posts[?(@.id == 1)]");
jsonPath.setCallback(posts, (parent, value) -> {
JSONArray array = (JSONArray) parent;
array.add(JSONObject.of("id", 3));
return value;
});
assertEquals(
"{\"posts\":[{\"id\":1,\"title\":\"ABC\"},{\"id\":2,\"title\":\"DEF\"},{\"id\":3}]}",
posts.toJSONString()
);
} |
@wenshao thanks, I understand, but we do not try to modify the existing object. We want a copy of it including tree structure/schema. The goal is to create a JSONObject of |
https://oss.sonatype.org/content/repositories/snapshots/com/alibaba/fastjson2/fastjson2/2.0.33-SNAPSHOT/ JSONPath path = JSONPath.of("$.posts[?(@.id == 1)]");
JSONPath p1 = path.getParent();
assertEquals("$.posts", p1.toString());
JSONPath p2 = p1.getParent();
assertEquals("$", p2.toString());
JSONPath p3 = p1.getParent();
assertNull(p3); @akelsch is it what you want? |
Actually yes, this is really useful because we can use How do you suggest should we determine if it is an array filter expression and we have to use |
https://oss.sonatype.org/content/repositories/snapshots/com/alibaba/fastjson2/fastjson2/2.0.33-SNAPSHOT/ JSONPath path = JSONPath.of("$.posts[?(@.id == 1)].id");
assertFalse(path.endsWithFilter());
JSONPath p0 = path.getParent();
assertEquals("$.posts[?(@.id == 1)]", p0.toString());
assertTrue(p0.endsWithFilter());
JSONPath p1 = p0.getParent();
assertEquals("$.posts", p1.toString());
assertFalse(p1.endsWithFilter());
JSONPath p2 = p1.getParent();
assertEquals("$", p2.toString());
assertFalse(p2.endsWithFilter()); |
@wenshao sorry for the delay. This works perfectly and covers our use case, thank you. Please release it to Maven Central for productive usage. |
https://github.com/alibaba/fastjson2/releases/tag/2.0.33 |
@wenshao it seems not to work with published version anymore? JSONPath p3 = JSONPath.of("$.posts[?(@.id == 1)]");
assertTrue(p3.endsWithFilter()); This fails because p3 is instance of |
Problem description
We expect
JSONPath.set
to successfully set a value into the first segment of a array filter expression but nothing happens.Environment information
Version info: Fastjson2 2.0.31
Steps to reproduce
Example JSON file:
Example Java code:
Expected correct result
In above code
eval
is evaluated correctly butset
does nothing. Instead we have to callset
usingJSONPath.of("$.posts")
which we do by modifying existing JSONPath string:StringUtils.substringBefore("$.posts[?(@.id == 1)]", "[")
. This might be unstable in case of nested array (multiple '[' character) so we expect the library to handle this case.We could have handled the case ourselves if
JSONPathTwoSegment
class would expose valuefirst
which in this case ispartners
. There are no methods in JSONPath abstract class to 1) expose all segment paths and 2) determine if it is an array filter expression either so everything is internal to the library with no access by users.The text was updated successfully, but these errors were encountered: