Skip to content
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

feature request: add a flag to provide non-cumulative diff operations instead of ONLY patch ops #83

Open
solidatyoungdevdotnet opened this issue Nov 8, 2018 · 4 comments

Comments

@solidatyoungdevdotnet
Copy link

USE CASE: Build graphical editor for modifying custom json schema structure and text that includes a button to identify differences graphically for user to review. Differences should be displayed inline in the editor (think tooltip/annotations inside document)
We are trying to use Zjsonpatch as the diff engine to compare the original json doc to the edited json doc which works fairly well but the cumulative nature (requiring the previous op in the array to be applied before the current path resolves correctly) of the patch operations makes it impossible to match operations to nodes without actually munging the doc, especially as the complexity of the edits compound.

I would like to use zjsonpatch to build a diff UI on my custom json schema. IF jsonpatch could be made to provide paths that do not require any to be applied, then we would be able to build any UI on top of our schema and then "annotate" the document with the patch operations and allow the users to review them without knowing anything about the underlying technologies or schemas.
json obj 1:
{ "dateRevised": null, "children": [ { "type": "TITLEPART", "id": null, "sortIndex": 0, "children": [ { "type": "TEXT", "id": null, "sortIndex": 0, "children": [ { "children": [], "content": "This" }, { "children": [], "content": " is" }, { "children": [], "content": " a" }, { "children": [], "content": " test" } ], "scheme": null, "scriptOrientation": null, "bold": null, "italic": null, "underline": null } ] } ] }

Json obj 2:
{ "dateRevised": null, "children": [ { "type": "TITLEPART", "id": null, "sortIndex": 0, "children": [ { "type": "TEXT", "id": null, "sortIndex": 0, "children": [ { "children": [], "content": "is" }, { "children": [], "content": " test" } ], "scheme": null, "scriptOrientation": null, "bold": null, "italic": null, "underline": null } ] } ] }
Current Patch:
[{"op":"replace","path":"/children/0/children/0/children/0/content","value":"is"},{"op":"remove","path":"/children/0/children/0/children/1"},{"op":"remove","path":"/children/0/children/0/children/1"}]

What I would like to have is
[ {"op":"remove","path":"/children/0/children/0/children/0"},{"op":"replace","path":"/children/0/children/0/children/1/content","value":"is"}, {"op":"remove","path":"/children/0/children/0/children/2"}, ]

I am not an RFC 6902 expert but I'm thinking that simply altering the paths to identify the source node path without respect to other operations would cover 99% of my problems. Am I off base? does anyone else have this use case? how did you solve it?

@LouizFC
Copy link
Collaborator

LouizFC commented Nov 10, 2018

@solidatyoungdevdotnet I am sorry, but I could not understand exactly what you want.

For what I understand: You want that each operation of the resultant patch be a "standalone" operation instead of depending on each other sequentially?

In that case, depending on the complexity of your document, I would recommend you to use the "OMIT" flags and process all the remove and add operations yourself.

I could help you with that of course, but I believe that such feature would be out of this library scope

@LouizFC
Copy link
Collaborator

LouizFC commented Nov 10, 2018

In that case, depending on the complexity of your document, I would recommend you to use the "OMIT" flags and process all the remove and add operations yourself.

Sorry, I forgot to clarify this paragraph

By that, I mean, that, since you have this library do all the "heavy lifting" of creating all the diffs, you could calculate all this paths yourself, for example:
This given patch:

[ { "op": "remove", "path": "/children/0"}, { "op": "remove", "path": "/children/0"} ]

would become:

[ { "op": "remove", "path": "/children/0"}, { "op": "remove", "path": "/children/1"} ]

That's because you are removing the 0 position two times, so you could write code that process this "repeated" paths and calculate the real index of each operation.

I don't know if this is trivial or not, since haven't really thought about all the corner cases or other factors

@solidatyoungdevdotnet
Copy link
Author

how would I get just the DELTA ? you say

By that, I mean, that, since you have this library do all the "heavy lifting" of creating all the diffs, you could calculate all this paths yourself

How do I do that? The documentation for getting the diff/delta is pretty thin

@LouizFC
Copy link
Collaborator

LouizFC commented Nov 16, 2018

Sorry, I am not familiar with the term DELTA.

What I meant was: You could set the all the OMIT flags on your JsonDiff:

EnumSet<DiffFlags> flags = DiffFlags.dontNormalizeOpIntoMoveAndCopy().clone()
JsonNode patch = JsonDiff.asJson(JsonNode source, JsonNode target, flags)

Them get all path properties on your "patch objects' and calculate the correct paths using a algorithm.

I could help you come up with a solution. Can you please provide a more complex example? Preferably one that alter many "levels" on the json and alter fields and indexes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants