2012-06-14 33 views
10

Por ejemplo, si tengo los siguientes textos: JSONdetectar diferencias entre dos archivos JSON en C#

object1{ 
    field1: value1; 
    field2: value2; 
    field3: value3; 
} 

object1{ 
    field1: value1; 
    field2: newvalue2; 
    field3: value3; 
} 

necesito algo en C# que dice que los archivos y muestra la diferencia. es decir, puede devolver el siguiente objeto:

differences { 
    object1: { field: field2, old_value: value2, new_value: newvalue2} 
} 

¿Hay alguna API o sugerencia para hacer esto?

+0

No es que yo sepa. Pero si escribes uno, publica un enlace aquí. :) –

Respuesta

4

le recomiendo que utilice Weakly-Typed JSON Serialization y escribir una rutina que utiliza JsonObject así:

String JsonDifferenceReport(String objectName, 
          JsonObject first, 
          JsonObject second) 
{ 
    if(String.IsNullOrEmpty(objectName)) 
    throw new ArgumentNullException("objectName"); 
    if(null==first) 
    throw new ArgumentNullException("first"); 
    if(null==second) 
    throw new ArgumentNullException("second"); 
    List<String> allKeys = new List<String>(); 
    foreach(String key in first.Keys) 
    if (!allKeys.Any(X => X.Equals(key))) allKeys.Add(key); 
    foreach(String key in second.Keys) 
    if (!allKeys.Any(X => X.Equals(key))) allKeys.Add(key); 
    String results = String.Empty; 
    foreach(String key in allKeys) 
    { 
    JsonValue v1 = first[key]; 
    JsonValue v1 = second[key]; 
    if (((null==v1) != (null==v2)) || !v1.Equals(v2)) 
    { 
     if(String.IsNullOrEmpty(results)) 
     { 
     results = "differences: {\n"; 
     } 
     results += "\t" + objectName + ": {\n"; 
     results += "\t\tfield: " + key + ",\n"; 
     results += "\t\toldvalue: " + (null==v1)? "null" : v1.ToString() + ",\n"; 
     results += "\t\tnewvalue: " + (null==v2)? "null" : v2.ToString() + "\n"; 
     results += "\t}\n"; 
    } 
    } 
    if(!String.IsNullOrEmpty(results)) 
    { 
    results += "}\n"; 
    } 
    return results; 
} 

Su elección si para obtener informes de forma recursiva en el interior JsonValue v1 y v2, en lugar de usar su representación de cadena como lo hice aquí .

Si quería ir recursivo, que podría cambiar lo anterior así:

if ((null==v1) || (v1.JsonType == JsonType.JsonPrimitive) 
    || (null==v2) || (v2.JsonType == JsonType.JsonPrimitive)) 
    { 
    results += "\t\tfield: " + key + ",\n"; 
    results += "\t\toldvalue: " + (null==v1) ? "null" : v1.ToString() + ",\n"; 
    results += "\t\tnewvalue: " + (null==v2) ? "null" : v2.ToString() + "\n"; 
    } 
    else 
    { 
    results + JsonDifferenceReport(key, v1, v2); 
    } 

-Jesse

1

Por alguna razón, yo no era capaz de utilizar JSONObject en mi proyecto Web API. Usé JSON.Net y debajo está mi método para obtener diff. Dará una matriz de diferencias.

private static string GetJsonDiff(string action, string existing, string modified, string objectType) 
    { 
     // convert JSON to object 
     JObject xptJson = JObject.Parse(modified); 
     JObject actualJson = JObject.Parse(existing); 

     // read properties 
     var xptProps = xptJson.Properties().ToList(); 
     var actProps = actualJson.Properties().ToList(); 

     // find differing properties 
     var auditLog = (from existingProp in actProps 
      from modifiedProp in xptProps 
      where modifiedProp.Path.Equals(existingProp.Path) 
      where !modifiedProp.Value.Equals(existingProp.Value) 
      select new AuditLog 
      { 
       Field = existingProp.Path, 
       OldValue = existingProp.Value.ToString(), 
       NewValue = modifiedProp.Value.ToString(), 
       Action = action, ActionBy = GetUserName(), 
       ActionDate = DateTime.UtcNow.ToLongDateString(), 
       ObjectType = objectType 
      }).ToList(); 

     return JsonConvert.SerializeObject(auditLog); 
    } 
Cuestiones relacionadas