Basically the new write API is a great step forward but a little cumbersome and
I've been pressed into writing a wrapper around it which doesn't seem right.
JsonPath.parse(DOC).set("$.a",1); // This is fine - replaces existing values
only
JsonPath.parse("{}").put("$","a",1); // This is equivalent but is difficult to
work with
It only operates on the direct children of the basepath and insists on the
client supplying the basebath seperately to a (potentially) new key. It feels
like the underlying object-graph, though still hidden, is distorting the
jsonpath interface.
I propose two levels of improvement (can split this enhancement request after
discussion maybe)
A) Infer the parent
This single-argument put still only works on immediate children but does not
require splitting. The path is compiled, evaluated up to the parent of the leaf
node and all matches are then set (amend-or-new).
JsonPath.parse("{}").put("$.a",1) = {"a":1}
JsonPath.parse("{"a":{}}").put("$..a.b",1) = {"a":{"b":1}}
JsonPath.parse("[{},{}]").put("$[0].b",1) = [{"b":1},{}]
JsonPath.parse("[{},{}]").put("$[0]",1) = [1,{}] // This one may be a little harder than others?
Need to think about the impact of puts made on the initial results (you might
have completely removed a subtree that contained a further match). My thoughts
were are to sort by absolute path length and convert the longest ones first but
then i realise filters still "look ahead"... Hence, I think this would simply
be a documented user-beware case.
B) Create deterministic parents
Using the compiled path, it should be possible to create the structure
deterministically implied by the request.
JsonPath.parse("{}").put("$.a.b",1) = {"a":{"b":1}}
JsonPath.parse("{}").put("$.a[1].b",1) = {"a":[null,{"b":1}]}
non-determinite path steps are selectors-only.
JsonPath.parse("{}").put("$.a[*].b",1) = {};
JsonPath.parse("{"a":[null]}").put("$.a[*].b",1) = {"a":[{"b":1}]};
JsonPath.parse("{"a":1,"b":{}}").put("$.a[*].b",1) = {"a":[{"b":1}]};
This should be a new verb but I can't think of one without changing the
existing ones
set -> replace
put -> set
(note it would be exactly equivalent in function so existing "set" users wouldn't notice)
put = put-with-create
What version of the product are you using? On what operating system?
1.2.0
Original issue reported on code.google.com by drekb...@gmail.com on 27 Nov 2014 at 2:04
Original issue reported on code.google.com by
drekb...@gmail.com
on 27 Nov 2014 at 2:04