Link to home
Start Free TrialLog in
Avatar of IzzyTwinkly
IzzyTwinklyFlag for United States of America

asked on

Parsing multi-layer Json string with Json.net and C#

Hi guys,

Today I found this Json string which looks very complicate to me. It's multi-layered!!!

I re-formatted little bit.  Here is what I got:

[
      {
        "Key": "Running",
        "Value": "[
                  {\"Key\":\"meter\",\"Value\":\"[
                                          {\\\"Key\\\":\\\"100\\\",\\\"Value\\\":\\\"12\\\"},
                                          {\\\"Key\\\":\\\"10000\\\",\\\"Value\\\":\\\"1900\\\"},
                                          {\\\"Key\\\":\\\"relay\\\",\\\"Value\\\":\\\"20000\\\"}
                                          ]\"},
                  {\"Key\":\"mile\",\"Value\":\"[
                                          {\\\"Key\\\":\\\"100\\\",\\\"Value\\\":\\\"2390\\\"},
                                          {\\\"Key\\\":\\\"10000\\\",\\\"Value\\\":\\\"0.0\\\"},      
                                          {\\\"Key\\\":\\\"relay\\\",\\\"Value\\\":\\\"90000\\\"}
                                         ]\"}
              ]"
          },
      {
        "Key": "Interval",
        "Value": "[
                  {\"Key\":\"Undefined\",\"Value\":\"[
                                                {\\\"Key\\\":\\\"100\\\",\\\"Value\\\":\\\"1\\\"},
                                                {\\\"Key\\\":\\\"10000\\\",\\\"Value\\\":\\\"Undefined\\\"}
                                             ]\"}
              ]"
          }

]
I tried to use 'KeyValuePair<string, string>[]' and foreach loop, but this is multi layer Json string, so it didn't work out well. :(
I am trying to solve this problem using Json.net and C#.

Can you please show me how to solve this issue?
ASKER CERTIFIED SOLUTION
Avatar of louisfr
louisfr

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of IzzyTwinkly

ASKER

Hi louisfr,

Thanks for your answer, but it didn't go well. I included the entire code below. They are inside Main method.
 var jsonString = @"[ 
      {
        ""Key"": ""Running"",
        ""Value"": ""[
                  {\""Key\"":\""meter\"",\""Value\"":\""[
                                          {\\\""Key\\\"":\\\""100\\\"",\\\""Value\\\"":\\\""12\\\""},
                                          {\\\""Key\\\"":\\\""10000\\\"",\\\""Value\\\"":\\\""1900\\\""},
                                          {\\\""Key\\\"":\\\""relay\\\"",\\\""Value\\\"":\\\""20000\\\""}
                                          ]\""},
                  {\""Key\"":\""mile\"",\""Value\"":\""[
                                          {\\\""Key\\\"":\\\""100\\\"",\\\""Value\\\"":\\\""2390\\\""},
                                          {\\\""Key\\\"":\\\""10000\\\"",\\\""Value\\\"":\\\""0.0\\\""},      
                                          {\\\""Key\\\"":\\\""relay\\\"",\\\""Value\\\"":\\\""90000\\\""}
                                         ]\""}
              ]""
          },
      {
        ""Key"": ""Interval"",
        ""Value"": ""[
                  {\""Key\"":\""Undefined\"",\""Value\"":\""[
                                                {\\\""Key\\\"":\\\""100\\\"",\\\""Value\\\"":\\\""1\\\""},
                                                {\\\""Key\\\"":\\\""10000\\\"",\\\""Value\\\"":\\\""Undefined\\\""}
                                             ]\""}
              ]""
          }

]";


             Dictionary<string, Dictionary<string, string>> result =
             ((KeyValuePair<string, string>[])JsonConvert.DeserializeObject(jsonString, typeof(KeyValuePair<string, string>[]))).ToDictionary(kvp => kvp.Key,
                             kvp => ((KeyValuePair<string, string>[])JsonConvert.DeserializeObject(kvp.Value, typeof(KeyValuePair<string, string>[]))).ToDictionary(kv => kv.Key, kv => kv.Value));

            foreach (var item in result)
        	{
		        Console.WriteLine("{0}: {1}", item.Key, item.Value);
	        }
   
        Console.ReadLine();

Open in new window


When I ran this code, I received the following result:
Running: System.Collections.Generic.Dictionary`2[System.String,System.String]
Interval: System.Collections.Generic.Dictionary`2[System.String,System.String]

I wanted it to be printed like:
Running
      meter
             100: 12
            10000: 1900
            relay: 2000
      mile
            100:2390
            10000: 0.0
            relay: 90000
Interval
      undefined
            100: 1
            10000: undefined
It's n-layer, so I thought that it should be recursive.
sorry I think that I should have been more descriptive.
I tried to resolve this issue with your solution during the weekend, but no luck so far.
could you please take a look at it?
this is the closest solution I have.
Thanks!
Avatar of louisfr
louisfr

I'll try to work out some code for multiple layers. But not right now.
Here's code for multiple layers. Convert method creates the dictionary. Print method prints it.
static Dictionary<string, object> Convert(string jsonString)
{
    Dictionary<string, object> result = new Dictionary<string,object>();
    foreach (KeyValuePair<string, string> kv in (KeyValuePair<string, string>[])JsonConvert.DeserializeObject(jsonString, typeof(KeyValuePair<string, string>[])))
    {
        object value=kv.Value;
        if (kv.Value.StartsWith("["))
        {
            try
            {
                value = Convert(kv.Value);
            }
            catch (Exception e)
            {
            }
        }
        result.Add(kv.Key, value);
    }
    return result;
}
static void Print(Dictionary<string, object> dict, int level = 0)
{
    foreach (KeyValuePair<string, object> kv in dict)
    {
        Dictionary<string, object> subdict = kv.Value as Dictionary<string, object>;
        Console.Write(new string(' ', 3 * level));
        if (subdict == null)
        {
            Console.WriteLine("{0}: {1}", kv.Key, kv.Value);
        }
        else
        {
            Console.WriteLine("{0}", kv.Key);
            Print(subdict, level + 1);
        }
    }
}

Dictionary<string, object> result = Convert(jsonString);
Print(result);

Open in new window