I'm using jsondiffpatch to generate diffs on OOXML documents in order to efficiently track updates that the user has made. This works great for simple cases where the content was updated, or the document is trivially short, but then I realized that if a paragraph is added or removed from the document, it will create a huge diff for the entire document content for all paragraphs thereafter. This is a well known problem, and the solution of using objectHash is spelled out in the documentation.
However, in Microsoft's infinite wisdom, OOXML nodes don't contain any sort of stable, unique identifier. That's okay, I can do a full content check against the node (using safe-stable-stringify) - it's less efficient, but it should work. However, what I instead discovered is that, by providing an objectHash function, it runs against every array that it sees. This means that as soon as we hit any top level array in the data structure, it'll generate a representation of the entire document, determine that they are not equal, and then consider the entire document has changed.
I think what I expect to happen is for the library to first determine the deepest part of the tree that contains an array with a diff, and then at that point use the given objectHash function to determine if the objects in that array are equal.
I hope I'm understanding the docs correctly; I'd love to be wrong and for this to be user error.
Here's an example diff generated from the simple case where a single paragraph is edited to demonstrate the heavily nested object structure that I'm working with:
{
"3": {
"pkg:package": {
"1": {
"pkg:part": {
"0": {
"pkg:xmlData": {
"0": {
"w:document": {
"0": {
"w:body": {
"18": {
"w:p": {
"2": {
"w:r": {
"1": {
"w:t": {
"0": {
"#text": [
"shall for the purpose of this Agreement mean any person or an entity which directly or indirectly holds twenty percent (20%) or more of the equity interest in such entity.",
"shall for the purpose of this Agreement mean any person "
]
},
"_t": "a"
},
":@": [
{
"@_xml:space": "preserve"
}
]
},
"_t": "a"
}
},
"3": [
{
"w:r": [
{
"w:rPr": [
{
"w:sz": [],
":@": {
"@_w:val": "22"
}
},
{
"w:szCs": [],
":@": {
"@_w:val": "22"
}
}
]
},
{
"w:t": [
{
"#text": "this is text that was inserted "
}
],
":@": {
"@_xml:space": "preserve"
}
}
]
}
],
"4": [
{
"w:r": [
{
"w:rPr": [
{
"w:sz": [],
":@": {
"@_w:val": "22"
}
},
{
"w:szCs": [],
":@": {
"@_w:val": "22"
}
}
]
},
{
"w:t": [
{
"#text": "or an entity which directly or indirectly holds twenty percent (20%) or more of the equity interest in such entity."
}
]
}
]
}
],
"_t": "a"
},
":@": {
"@_w14:textId": [
"105EC127",
"31CBDF56"
]
}
},
"_t": "a"
}
},
"_t": "a"
}
},
"_t": "a"
}
},
"_t": "a"
}
},
"_t": "a"
}
},
"_t": "a"
}
I'm using
jsondiffpatchto generate diffs on OOXML documents in order to efficiently track updates that the user has made. This works great for simple cases where the content was updated, or the document is trivially short, but then I realized that if a paragraph is added or removed from the document, it will create a huge diff for the entire document content for all paragraphs thereafter. This is a well known problem, and the solution of usingobjectHashis spelled out in the documentation.However, in Microsoft's infinite wisdom, OOXML nodes don't contain any sort of stable, unique identifier. That's okay, I can do a full content check against the node (using safe-stable-stringify) - it's less efficient, but it should work. However, what I instead discovered is that, by providing an
objectHashfunction, it runs against every array that it sees. This means that as soon as we hit any top level array in the data structure, it'll generate a representation of the entire document, determine that they are not equal, and then consider the entire document has changed.I think what I expect to happen is for the library to first determine the deepest part of the tree that contains an array with a diff, and then at that point use the given
objectHashfunction to determine if the objects in that array are equal.I hope I'm understanding the docs correctly; I'd love to be wrong and for this to be user error.
Here's an example diff generated from the simple case where a single paragraph is edited to demonstrate the heavily nested object structure that I'm working with: