Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Canonicalizing JSON files

Tags:

java

json

ruby

I have a bunch of automatically generated JSON files that I want to store in version control. The problem is that each time the files are serialized, the attributes come out in a different order, making it hard to know if the files have really changed and / or what the real differences are.

Does anyone know of an existing open source tool that will perform this task?

Failing that, does anyone know of a JSON library with a parser and a generator that can be configured to output "pretty" JSON with the attributes in (say) lexical order? (A Java or Ruby library would be ideal, but other leads are also welcome.)

like image 927
Stephen C Avatar asked Sep 25 '12 14:09

Stephen C


2 Answers

Python's JSON module is very usable from other programs:

generate_json | python -mjson.tool > canonical.json 
like image 184
Martin Vidner Avatar answered Sep 21 '22 13:09

Martin Vidner


If you're willing to go through a bit of overhead by calling

gson.toJson(canonicalize(gson.toJsonTree(obj))); 

Then you can do something like this:

protected static JsonElement canonicalize(JsonElement src) {   if (src instanceof JsonArray) {     // Canonicalize each element of the array     JsonArray srcArray = (JsonArray)src;     JsonArray result = new JsonArray();     for (int i = 0; i < srcArray.size(); i++) {       result.add(canonicalize(srcArray.get(i)));     }     return result;   } else if (src instanceof JsonObject) {     // Sort the attributes by name, and the canonicalize each element of the object     JsonObject srcObject = (JsonObject)src;     JsonObject result = new JsonObject();     TreeSet<String> attributes = new TreeSet<>();     for (Map.Entry<String, JsonElement> entry : srcObject.entrySet()) {       attributes.add(entry.getKey());     }     for (String attribute : attributes) {       result.add(attribute, canonicalize(srcObject.get(attribute)));     }     return result;   } else {     return src;   } } 
like image 26
Andrew Sacamano Avatar answered Sep 20 '22 13:09

Andrew Sacamano