1

Using Newtonsoft.Json how do I convert a JSON object into a dictionary with Path being the key?

IDictionary<string, object> FlattenJson(string Json)
{
  JToken Input = JToken.Parse(Json);

  ... magic ...

  return Result;
}

Key of the dictionary shall be the JToken.Path value and Value of the dictionary shall be the actual value in its "native" format (string as string, integer a long, etc).

"message.body.titles[0].formats[0].images[0].uri" => "I/41SKCXdML._SX160_SY120_.jpg" "message.body.titles[0].formats[0].images[0].widthPx" => 0 "message.body.titles[0].customerReviewsCollectionIncluded" => False ...

Is there anything out-of-the-box that works for arbitrary JSON?

hopperpl
  • 298
  • 3
  • 8
  • I don't think there is anything out of the box that does this. Are you sure the JToken.Path is unique so that you can use it as a key? – su8898 Jan 02 '15 at 22:07
  • possible duplicate of [C# flattening json structure](http://stackoverflow.com/questions/7394551/c-sharp-flattening-json-structure) – Jacob Jan 03 '15 at 00:04
  • @Jacob - I don't think this is a duplicate. That answer won't handle arrays, and uses a somewhat different scheme for defining the key text. – dbc Jan 03 '15 at 20:19

1 Answers1

1

You need to recursively traverse the Json.NET hierarchy, pick out the primitive values (which have type JValue), and store their values in the dictionary, like so:

public static class JsonExtensions
{
    public static IEnumerable<JToken> WalkTokens(this JToken node)
    {
        if (node == null)
            yield break;
        yield return node;
        foreach (var child in node.Children())
            foreach (var childNode in child.WalkTokens())
                yield return childNode;
    }

    public static IDictionary<string, object> ToValueDictionary(this JToken root)
    {
        return root.WalkTokens().OfType<JValue>().ToDictionary(value => value.Path, value => value.Value);
    }
}

And then call it like

var Result = Input.ToValueDictionary();

Note that integers will be stored as Int64.

dbc
  • 104,963
  • 20
  • 228
  • 340