C # json structure compression

I have a json object in C # (represented as a Newtonsoft.Json.Linq.JObject object) and I need to smooth it in a dictionary. Let me show you an example of what I mean:

{ "name": "test", "father": { "name": "test2" "age": 13, "dog": { "color": "brown" } } } 

This will give a dictionary with the following key-value pairs:

 ["name"] == "test", ["father.name"] == "test2", ["father.age"] == 13, ["father.dog.color"] == "brown" 

How can i do this?

+20
json c # data-structures recursion
source share
3 answers
 JObject jsonObject=JObject.Parse(theJsonString); IEnumerable<JToken> jTokens = jsonObject.Descendants().Where(p => p.Count() == 0); Dictionary<string, string> results = jTokens.Aggregate(new Dictionary<string, string>(), (properties, jToken) => { properties.Add(jToken.Path, jToken.ToString()); return properties; }); 

I had the same requirement of smoothing a nested json structure into a dictionary object. Found solution here .

+23
source share

You can use https://github.com/jsonfx/jsonfx to deserialize json into a dynamic object. Then use ExpandoObject to get what you want.

 public Class1() { string json = @"{ ""name"": ""test"", ""father"": { ""name"": ""test2"", ""age"": 13, ""dog"": { ""color"": ""brown"" } } }"; var reader = new JsonFx.Json.JsonReader(); dynamic output = reader.Read(json); Dictionary<string, object> dict = new Dictionary<string, object>(); GenerateDictionary((System.Dynamic.ExpandoObject) output, dict, ""); } private void GenerateDictionary(System.Dynamic.ExpandoObject output, Dictionary<string, object> dict, string parent) { foreach (var v in output) { string key = parent + v.Key; object o = v.Value; if (o.GetType() == typeof(System.Dynamic.ExpandoObject)) { GenerateDictionary((System.Dynamic.ExpandoObject)o, dict, key + "."); } else { if (!dict.ContainsKey(key)) { dict.Add(key, o); } } } } 
+4
source share

I actually had the same problem earlier today, I could not find this question on SO at first, and as a result I wrote my own extension method to return JValue objects containing leaf node values โ€‹โ€‹of the JSON blob. This is similar to the accepted answer, with the exception of some improvements:

  1. It processes any JSON that you give it (arrays, properties, etc.), and not just a JSON object.
  2. Less memory usage
  3. No .Count() calls for descendants that you ultimately don't need

Depending on your use case, they may or may not be relevant, but they are for my case. I wrote about learning to align JSON.NET objects on my blog . Here is the extension method I wrote:

 public static class JExtensions { public static IEnumerable<JValue> GetLeafValues(this JToken jToken) { if (jToken is JValue jValue) { yield return jValue; } else if (jToken is JArray jArray) { foreach (var result in GetLeafValuesFromJArray(jArray)) { yield return result; } } else if (jToken is JProperty jProperty) { foreach (var result in GetLeafValuesFromJProperty(jProperty)) { yield return result; } } else if (jToken is JObject jObject) { foreach (var result in GetLeafValuesFromJObject(jObject)) { yield return result; } } } #region Private helpers static IEnumerable<JValue> GetLeafValuesFromJArray(JArray jArray) { for (var i = 0; i < jArray.Count; i++) { foreach (var result in GetLeafValues(jArray[i])) { yield return result; } } } static IEnumerable<JValue> GetLeafValuesFromJProperty(JProperty jProperty) { foreach (var result in GetLeafValues(jProperty.Value)) { yield return result; } } static IEnumerable<JValue> GetLeafValuesFromJObject(JObject jObject) { foreach (var jToken in jObject.Children()) { foreach (var result in GetLeafValues(jToken)) { yield return result; } } } #endregion } 

Then in my calling code, I simply extract the Path and Value properties from the JValue of JValue objects:

 var jToken = JToken.Parse("blah blah json here"); foreach (var jValue in jToken.GetLeafValues()) { Console.WriteLine("{0} = {1}", jValue.Path, jValue.Value); } 
+1
source share

All Articles