2

I have a csv file that contains paths and values in the following format:

path;value
prop1.prop2.1;hello
prop1.prop2.2;world
prop1.prop2.3;!
prop1.prop3.test;hi
prop1.prop4;value

And I wand to get it as json:

{
  "prop1": {
    "prop2": {
      "1": "hello",
      "2": "world",
      "3": "!"
    }
    "prop3": {
      "test": "hi"
    }
    "prop4": "value"
  }    
}

I've parsed csv file like this:

Dictionary<string, string> dict = new Dictionary<string, string>();
while (csv.Read())
{
  string path = csv.GetField<string>(0);
  string value = csv.GetField<string>(1);
  dict.Add(path, value);
}

Could you help me with method, that will create JSON from this dictionary using JSON.Net Library. Of course properties in original file can be different.

3 Answers 3

1

You can use this function to get the Json back as a string from your Dictionary

public static string BuildJson(Dictionary<string, string> dict)
{
    dynamic expando = new ExpandoObject();

    foreach (KeyValuePair<string, string> pair in dict.Where(x => !string.Equals(x.Key, "path")))
    {
        string[] pathArray = pair.Key.Split('.');
        var currentExpando = expando as IDictionary<string, Object>;

        for (int i = 0; i < pathArray.Count(); i++)
        {
            if (i == pathArray.Count() - 1)
            {
                currentExpando.Add(pathArray[i], pair.Value);
            }
            else
            {
                if (!currentExpando.Keys.Contains(pathArray[i]))
                {
                    currentExpando.Add(pathArray[i], new ExpandoObject());
                }
                currentExpando = currentExpando[pathArray[i]] as IDictionary<string, Object>;
            }
        }
    }

    JObject o = JObject.FromObject(expando);
    return o.ToString();
}

you need to add a using System.Dynamic;

Sign up to request clarification or add additional context in comments.

1 Comment

It works great, but it fails when you have one property like: prop1.prop2.prop2
1

You can take advantage of System.Dynamic.ExpandoObject:

public string ToJson(Dictionary<string, string> props)
{
    IDictionary<string, object> json = new System.Dynamic.ExpandoObject() as IDictionary<string, object>;

    foreach (var prop in props)
    {
        string path = prop.Key;
        if (String.IsNullOrWhiteSpace(path)) continue;
        string[] keys = path.Split('.');

        string value = prop.Value;

        var cursor = json;

        for (int i = 0; i < keys.Length; i++)
        {
            object innerJson;
            if (!cursor.TryGetValue(keys[i], out innerJson))
                cursor.Add(keys[i], new System.Dynamic.ExpandoObject() as IDictionary<string, object>);
            if (i == keys.Length - 1)
                cursor[keys[i]] = value;

            cursor = cursor[keys[i]] as IDictionary<string, object>;
        }

    }

    return JsonConvert.SerializeObject(json);
}

Comments

0

Without using dynamic:

Dictionary<string, object> dictionary = new Dictionary<string, object>();
while (csv.Read())
{
  string path = csv.GetField<string>(0);
  string value = csv.GetField<string>(1);
  dictionary = GetHierarchy(path, value);
}
string serialized = JsonConvert.SerializeObject(dictionary);
Console.WriteLine(serialized);

Add following method:

public Dictionary<string, object> GetHierarchy(Dictionary<string, object> root, string path, string value)
{
    string[] parts = path.Split('.');
    if (parts.Length > 1)
    {
        if(!root.ContainsKey(parts[0]))
            root.Add(parts[0], new Dictionary<string, object>());
        Dictionary<string, object> dict = root[parts[0]] as Dictionary<string, object>;
        GetMe(dict, path.Replace(parts[0] + ".", string.Empty), value);
    }
    else 
        root[parts[0]] = value;
    return root;
}

Generates the expected output

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.