Get With the Times - Get Rid Of the Bloated XML Data Format And Switch To JSON

 

Get With the Times - Get Rid Of the Bloated XML Data Format And Switch To JSON

Rate This
  • Comments 4
  1. One of my blog readers told me it was 2014

  2. He laughed at the fact that I was still using XML

  3. So within 30 minutes I was writing JSON to disk, instead of XML

  4. It was incredibly easy to do

  5. It is much easier than you might expect

  6. I eliminated an un-needed class and persisted my data into a smaller payload

INSTALL THE NUGET PACKAGE FOR JSON.NET

  1. In Visual Studio use the Tools menu

    image001

    Figure 1: Adding a NuGet Package - Json.Net

THE OLD XML-BASED APPROACH

  1. This is the code that I eliminated to Json-ify it

    • Line 15 and 50 were changed to make it Json
    • Lines 71 to 104 were eliminated
Old, XML Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//  Old Code using XML
//
//
private static async Task SaveToDiskFolders(ObservableCollection<FoldersItem> collection, string filename)
{
    // Creat a save-able object list
    List<FoldersItemDisk> dataToSave = new List<FoldersItemDisk>();
    foreach (FoldersItem item in collection)
    {
        dataToSave.Add(new FoldersItemDisk { FolderName = item.FolderName });
    }

    // Make xml out of it
    string localData = ObjectSerializer<List<FoldersItemDisk>>.ToXml(dataToSave);

    // Save to disk part 1
    StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
    StorageFile storageFile =
            await storageFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);

    // Save to disk part 2
    using (IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.ReadWrite))
    {
        using (DataWriter dataWriter = new DataWriter(stream))
        {
            dataWriter.WriteString(localData);
            await dataWriter.StoreAsync();
        }
    }
}



private async Task ReadFromFileFolders(ObservableCollection<FoldersItem> collection, ResetCollectionWithSource myfunc, string filename)
{
    try
    {
        StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
        StorageFile storageFile =
                await storageFolder.GetFileAsync(filename);

        using (IRandomAccessStreamWithContentType readStream = await storageFile.OpenReadAsync())
        using (DataReader reader = new DataReader(readStream))
        {
            ulong streamSize = readStream.Size;
            UInt32 totalBytesRead = await reader.LoadAsync((UInt32)streamSize);

            string s = reader.ReadString(totalBytesRead);
            List<FoldersItemDisk> localData = ObjectSerializer<List<FoldersItemDisk>>.FromXml(s);
            collection.Clear();
            foreach (FoldersItemDisk item in localData)
            {
                collection.Add(new FoldersItem {
                        FolderName = item.FolderName,
                        Folder = await StorageFolder.GetFolderFromPathAsync(item.FolderName)
                });
            }
            myfunc();
           
        }
    }
    catch (FileNotFoundException)
    {

    }

}


internal static class ObjectSerializer<T>
{
        // Serialize to xml
        public static string ToXml(T value)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            StringBuilder stringBuilder = new StringBuilder();
            XmlWriterSettings settings = new XmlWriterSettings()
            {
                Indent = true,
                OmitXmlDeclaration = true,
            };

            using (XmlWriter xmlWriter = XmlWriter.Create(stringBuilder, settings))
            {
                serializer.Serialize(xmlWriter, value);
            }
            return stringBuilder.ToString();
        }

        // Deserialize from xml
        public static T FromXml(string xml)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            T value;
            using (StringReader stringReader = new StringReader(xml))
            {
                object deserialized = serializer.Deserialize(stringReader);
                value = (T)deserialized;
            }

            return value;
        }
}

THE NEW, MODERN, JSON-BASED APPROACH

  1. After adding the Json.NET package, I just changed the code to look like this

    • Lines 15 to 18 are new
    • Lines 54 to 57 are new
New, Json Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//  New Code using JSON
//
//
private static async Task SaveToDiskFolders(ObservableCollection<FoldersItem> collection, string filename)
{
    // Creat a save-able object list
    List<FoldersItemDisk> dataToSave = new List<FoldersItemDisk>();
    foreach (FoldersItem item in collection)
    {
        dataToSave.Add(new FoldersItemDisk { FolderName = item.FolderName });
    }

    // New JSON approach
    string localData = JsonConvert.SerializeObject(dataToSave, new JsonSerializerSettings
    {
        Formatting = Formatting.Indented
    });


    // Save to disk part 1
    StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
    StorageFile storageFile =
            await storageFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);

    // Save to disk part 2
    using (IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.ReadWrite))
    {
        using (DataWriter dataWriter = new DataWriter(stream))
        {
            dataWriter.WriteString(localData);
            await dataWriter.StoreAsync();
        }
    }
}



private async Task ReadFromFileFolders(ObservableCollection<FoldersItem> collection, ResetCollectionWithSource myfunc, string filename)
{
    try
    {
        StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
        StorageFile storageFile =
                await storageFolder.GetFileAsync(filename);

        using (IRandomAccessStreamWithContentType readStream = await storageFile.OpenReadAsync())
        using (DataReader reader = new DataReader(readStream))
        {
            ulong streamSize = readStream.Size;
            UInt32 totalBytesRead = await reader.LoadAsync((UInt32)streamSize);

            string s = reader.ReadString(totalBytesRead);
            List<FoldersItemDisk> localData = JsonConvert.DeserializeObject<List<FoldersItemDisk>>(s, new JsonSerializerSettings
            {
                Formatting = Formatting.Indented
            });
            collection.Clear();
            foreach (FoldersItemDisk item in localData)
            {
                collection.Add(new FoldersItem {
                        FolderName = item.FolderName,
                        Folder = await StorageFolder.GetFolderFromPathAsync(item.FolderName)
                });
            }
            myfunc();
           
        }
    }
    catch (FileNotFoundException)
    {

    }

}

Conclusion

Now is the time to go to your code and bring it into 2014.

  • wow. that was a fast change! awesome :)

  • All this json thing is nice and all, but good luck if you reuse the same object in multiple places of your hiearchy: only XML and DataContract(IsReference=true) will do the trick correctly.

    But Json is perfect for simpler things.

  • Now we need integration of JSON with MsSQL Engine as a new type ;-).

  • @tec - this can be done with JSON, too.

Page 1 of 1 (4 items)
Leave a Comment
  • Please add 8 and 3 and type the answer here:
  • Post