2

我正在使用 Google diff-match-patch JAVA 插件在两个 JSON 字符串之间创建补丁并将补丁存储到数据库中。

diff_match_patch dmp = new diff_match_patch();    
LinkedList<Patch> diffs = dmp.patch_make(latestString, originalString);
String patch = dmp.patch_toText(diffs); // Store patch to DB

现在有什么方法可以通过传递来使用它patch来重新创建?originalStringlatestString

我对此进行了谷歌搜索,发现这条非常古老的评论@Google diff-match-patch Wiki说,

只需循环 diff,将 DIFF_INSERT 与 DIFF_DELETE 交换,然后应用补丁即可完成取消修补。

但我没有找到任何有用的代码来证明这一点。我怎样才能用我现有的代码实现这一点?任何指针或代码参考将不胜感激。

编辑:

我面临的问题是,在前端我显示了一个修订模块,该模块显示了特定片段的所有事务(例如员工详细信息),例如哪个用户更新了哪些详细信息等。现在我正在重新创建通过反向应用每个补丁来分段 JSON 以获取当前事务数据并将其显示为表格(使用http://marianoguerra.github.io/json.human.js/)。但是一些 JSON 数据不是有效的 JSON,我收到 JSON.parse 错误。

4

1 回答 1

0

我正在寻找做类似的事情(在 C# 中),而使用相对简单的对象对我有用的是patch_apply方法。这个用例似乎在文档中有些缺失,所以我在这里回答。代码是 C#,但 API 是跨语言的:

static void Main(string[] args)
{
    var dmp = new diff_match_patch();

    string v1 = "My Json Object;            
    string v2 = "My Mutated Json Object"

    var v2ToV1Patch = dmp.patch_make(v2, v1);
    var v2ToV1PatchText = dmp.patch_toText(v2ToV1Patch);  // Persist text to db

    string v3 = "Latest version of JSON object;

    var v3ToV2Patch = dmp.patch_make(v3, v2);
    var v3ToV2PatchTxt = dmp.patch_toText(v3ToV2Patch);  // Persist text to db

    // Time to re-hydrate the objects 

    var altV3ToV2Patch = dmp.patch_fromText(v3ToV2PatchTxt);
    var altV2 = dmp.patch_apply(altV3ToV2Patch, v3)[0].ToString(); // .get(0) in Java I think           

    var altV2ToV1Patch = dmp.patch_fromText(v2ToV1PatchText);
    var altV1 = dmp.patch_apply(altV2ToV1Patch, altV2)[0].ToString(); 

}

我正在尝试将其改装为审计日志,以前保存了整个 JSON 对象。随着被审计对象变得越来越复杂,存储需求也急剧增加。我还没有将它应用到复杂的大对象上,但是可以通过检查patch_apply方法返回的数组中的第二个对象来检查补丁是否成功。这是一个布尔值数组,如果补丁正常工作,所有这些都应该是真的。您可以编写一些代码来检查这一点,这将有助于检查对象是否可以成功地从 JSON 中重新水化,而不仅仅是得到解析错误。我的原型 C# 方法如下所示:

private static bool ValidatePatch(object[] patchResult, out string patchedString)
{
    patchedString = patchResult[0] as string;

    var successArray = patchResult[1] as bool[];

    foreach (var b in successArray)
    {
        if (!b)
            return false;
    }

    return true;
}
于 2018-06-15T11:19:33.487 回答