/// <summary> /// compare two JArrays ignore the order, get get all diff patches /// </summary> /// <param name="mirror">mirror/left Json Array, all elements value must be basic value type</param> /// <param name="obj">object/right Json Array, all elements value must be basic value type</param> /// <param name="patches">the array collection to store all diff patches</param> private void diffJArrayNoOrder(JArray mirror, JArray obj, JArray patches) { int oldObjArrSize = mirror.Count; int newObjArrSize = obj.Count; foreach (JToken jToken in mirror) { //if (!obj.Contains(jToken)) // always return false, somthing wrong? //{ // string path = JsonPointer.ToJsonPointer(jToken.Path); // Patch patch = new Patch("remove", null, path, null); // patches.Add(patch.Value); //} bool has = false; foreach (JToken oJToken in obj) { if (JToken.DeepEquals(jToken, oJToken)) { has = true; break; } } if (!has) { string path = JsonPointer.ToJsonPointer(jToken.Path); Patch patch = new Patch("remove", null, path, null); patches.Add(patch.Value); } } foreach (JToken jToken in obj) { //if (!mirror.Contains(jToken)) //{ // string path = JsonPointer.ToJsonPointer(jToken.Path); // Patch patch = new Patch("add", null, path, jToken); // patches.Add(patch.Value); //} bool has = false; foreach (JToken mJToken in mirror) { if (JToken.DeepEquals(jToken, mJToken)) { has = true; break; } } if (!has) { string path = JsonPointer.ToJsonPointer(jToken.Path); Patch patch = new Patch("add", null, path, jToken); patches.Add(patch.Value); } } }
/// <summary> /// compare two JObjects,get all diff patches /// </summary> /// <param name="mirror">mirror/left Json Object</param> /// <param name="obj">object/right Json Object</param> /// <param name="patches">the array collection to store all diff patches</param> private void diffJObject(JObject mirror, JObject obj, JArray patches) { if (JToken.DeepEquals(mirror, obj)) { return; } IEnumerable <JProperty> newJProperties = obj.Properties(); IEnumerable <JProperty> oldJProperties = mirror.Properties(); foreach (JProperty jp in oldJProperties) { JToken oldValue = jp.Value; JToken newValue; if (OrdinalIgnoreCase) { newValue = obj.GetValue(jp.Name, StringComparison.OrdinalIgnoreCase); } else { newValue = obj.GetValue(jp.Name); } if (newValue == null) { string path = JsonPointer.ToJsonPointer(jp.Path); Patch patch = new Patch("remove", null, path, null); patches.Add(patch.Value); } else { string t = newValue.Type.ToString(); if ((newValue.Type == JTokenType.Object && oldValue.Type == JTokenType.Object)) { diffJObject((JObject)oldValue, (JObject)newValue, patches); } else if ((newValue.Type == JTokenType.Array && oldValue.Type == JTokenType.Array)) { JArray newArr = newValue as JArray; JArray oldArr = oldValue as JArray; if (NoOrderInBasicTypeValueJArray && IsNoDuplicateBasicTypeJArray(newArr) && IsNoDuplicateBasicTypeJArray(oldArr)) { diffJArrayNoOrder(oldArr, newArr, patches); } else { diffJArray(oldArr, newArr, patches); } } else { if (!JToken.DeepEquals(newValue, oldValue)) { string path = JsonPointer.ToJsonPointer(jp.Path); Patch patch = new Patch("replace", null, path, newValue); patches.Add(patch.Value); } } } } foreach (JProperty jp in newJProperties) { JToken newValue = jp.Value; JToken oldValue; if (OrdinalIgnoreCase) { oldValue = mirror.GetValue(jp.Name, StringComparison.OrdinalIgnoreCase); } else { oldValue = mirror.GetValue(jp.Name); } if (oldValue == null) { string path = JsonPointer.ToJsonPointer(jp.Path); Patch patch = new Patch("add", null, path, newValue); patches.Add(patch.Value); } } }
/// <summary> /// compare two JArrays, get get all diff patches /// </summary> /// <param name="mirror">mirror/left Json Array</param> /// <param name="obj">object/right Json Array</param> /// <param name="patches">the array collection to store all diff patches</param> private void diffJArray(JArray mirror, JArray obj, JArray patches) { if (NoOrderInBasicTypeValueJArray && IsNoDuplicateBasicTypeJArray(mirror) && IsNoDuplicateBasicTypeJArray(obj)) { diffJArrayNoOrder(mirror, obj, patches); return; } int oldObjArrSize = mirror.Count; int newObjArrSize = obj.Count; for (int i = 0; i < oldObjArrSize; i++) { JToken oldValue = mirror[i]; if (i < newObjArrSize) { JToken newValue = obj[i]; if ((newValue.Type == JTokenType.Object && oldValue.Type == JTokenType.Object)) { diffJObject((JObject)oldValue, (JObject)newValue, patches); } else if ((newValue.Type == JTokenType.Array && oldValue.Type == JTokenType.Array)) { JArray newArr = newValue as JArray; JArray oldArr = oldValue as JArray; if (NoOrderInBasicTypeValueJArray && IsNoDuplicateBasicTypeJArray(newArr) && IsNoDuplicateBasicTypeJArray(oldArr)) { diffJArrayNoOrder(oldArr, newArr, patches); } else { diffJArray(oldArr, newArr, patches); } } else { if (!JToken.DeepEquals(newValue, oldValue)) { string path = JsonPointer.ToJsonPointer(oldValue.Path); Patch patch = new Patch("replace", null, path, newValue); patches.Add(patch.Value); } } } else { string path = JsonPointer.ToJsonPointer(oldValue.Path); Patch patch = new Patch("remove", null, path, null); patches.Add(patch.Value); } } for (int i = 0; i < newObjArrSize; i++) { JToken newValue = obj[i]; if (i > oldObjArrSize - 1) { string path = JsonPointer.ToJsonPointer(newValue.Path); Patch patch = new Patch("add", null, path, newValue); patches.Add(patch.Value); } } }