1

I'm having trouble with merging a large JSON file using Git. Git seems to be unable to properly diff large JSON files. This solution of adding additional line breaks between each of the properties in a JSON object seems to resolve the merge conflicts.

The problem is that my JSON file is rather large and it is generated without line breaks. I also cannot control how it is generated. Here is a sample:

"notes":[
           {
                "__type__": "Note", 
                "data": "", 
                "fields": [
                    "Define virologic suppression in HIV", 
                    "HIV RNA level below limit of assay detection (<20copies/mL", 
                    "", 
                    ""
                ], 
                "flags": 0, 
                "guid": "B4VR%D9qb2", 
                "note_model_uuid": "0aecb5c4-d637-11e7-8e91-408d5c5c9416", 
                "tags": [
                    "InfectiousDiseases"
                ]
            }, 
            {
                "__type__": "Note", 
                "data": "", 
                "fields": [
                    "Define incomplete virological response in HIV", 
                    "Inability to achieve virologic suppression after 24 weeks of therapy (viral load >200 on 2 consecutive samples)", 
                    "", 
                    ""
                ], 
                "flags": 0, 
                "guid": "N{WL%;*sKr", 
                "note_model_uuid": "0aecb5c4-d637-11e7-8e91-408d5c5c9416", 
                "tags": [
                    "InfectiousDiseases"
                ]
            }
]

I'm trying to write a script to add the additional line breaks using JSON.net. Here is what I have so far:

    static void Main(string[] args)
    {
        using (StreamReader file = File.OpenText(@"fracp-anki.json"))
        using (var reader = new JsonTextReader(file))
        {
            JObject deck = (JObject)JToken.ReadFrom(reader);
            var notes = (JArray)deck["notes"];
            string paddedNotes = writePaddedNotes(notes);
            Console.WriteLine(paddedNotes);
        }

    }

    public static string writePaddedNotes(JArray notes)
    {
        StringBuilder sb = new StringBuilder();
        StringWriter sw = new StringWriter(sb);

        using (JsonWriter writer = new JsonTextWriter(sw))
        {
            foreach (var note in notes.Children<JObject>())
            {
                //what goes here?
            }
        }
        return sb.ToString();
    }

How do I write the properties of each object in the array to a file with an added line break between them?

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
Blake Mumford
  • 17,201
  • 12
  • 49
  • 67

1 Answers1

2

One way you could solve this is by subclassing the JsonTextWriter and overriding the WriteValueDelimiter method so that it writes an extra line break after the delimiter like so:

class DoubleSpacedValuesJsonWriter : JsonTextWriter
{
    public DoubleSpacedValuesJsonWriter(TextWriter textWriter) : base(textWriter)
    {
        Formatting = Formatting.Indented;
    }

    protected override void WriteValueDelimiter()
    {
        base.WriteValueDelimiter();
        base.WriteWhitespace(Environment.NewLine);
    }
}

Then you can make a short helper method to reformat your JSON file like this:

public static void ReformatJsonFile(string filename)
{
    string tempFile = filename + ".tmp";

    using (StreamReader sr = new StreamReader(filename))
    using (JsonReader reader = new JsonTextReader(sr))
    using (StreamWriter sw = new StreamWriter(tempFile))
    using (JsonWriter writer = new DoubleSpacedValuesJsonWriter(sw))
    {
        writer.WriteToken(reader);
    }

    File.Delete(filename);
    File.Move(tempFile, filename);
}

Here is a working demo (using the console instead of a file): https://dotnetfiddle.net/5ZVom7

If it turns out that you need additional line breaks after the opening and closing braces {} and/or brackets [] also, you can override the WriteStartObject, WriteEndObject, WriteStartArray and WriteEndArray methods in the same manner.

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300