0

I wish to parse a JSON file which is generated dynamically and does not have a definite structure.

[
  {
    "children": [
      {
        "children": [
          {
            "children": [],
            "text": "Child node 2.txt",
            "isFolder": false,
            "id": "1childnode2.txt",
            "itsPath": "C:\\Users\\pandyapa\\Root node\\Child node 2.txt",
            "type": "itsfile"
          }
        ],
        "text": "Child node 1.txt",
        "isFolder": false,
        "id": "0childnode1.txt",
        "itsPath": "C:\\Users\\pandyapa\\Root node\\Child node 1.txt",
        "type": "itsfile"
      },
      {
        "children": [],
        "text": "Child node 2.txt",
        "isFolder": false,
        "id": "1childnode2.txt",
        "itsPath": "C:\\Users\\pandyapa\\Root node\\Child node 2.txt",
        "type": "itsfile"
      },
      {
        "children": [],
        "text": "Child node 3.txt",
        "isFolder": false,
        "id": "2childnode3.txt",
        "itsPath": "C:\\Users\\pandyapa\\Root node\\Child node 3.txt",
        "type": "itsfile"
      }
    ],
    "text": "Root node",
    "isFolder": true,
    "id": "3rootnode",
    "itsPath": "C:\\Users\\pandyapa\\Root node",
    "type": "default"
  }
]

This JSON can have any nested children. I wish to parse each JSON object, compare its "id" key and retrieve the "itspath" value. I tried but was unsuccessful. Any help is highly appreciated.

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
Parth Pandya
  • 39
  • 1
  • 12

1 Answers1

0

It looks to me like your JSON does have a very definite structure, which can be represented by this recursive class:

public class Node
{
    public Node[] Children { get; set; }
    public string Text { get; set; }
    public bool IsFolder { get; set; }
    public string Id { get; set; }
    public string ItsPath { get; set; }
    public string Type { get; set; }
}

It may be that the JSON can be deeply nested and you may not know ahead of time how many levels or how many children there will be at each level, but the fact remains that each "node" has a uniform structure. This is good, because it means that it can be easily deserialized with a parser such as Json.Net. In fact, you can do it with just one line of code:

List<Node> nodes = JsonConvert.DeserializeObject<List<Node>>(json);

Once you have the nodes deserialized, you need to be able to find the one you want. By introducing a short "DescendantsAndSelf" method to the class, you can make the structure queryable using LINQ methods.

    public IEnumerable<Node> DescendantsAndSelf()
    {
        yield return this;
        if (Children != null)
        {
            foreach (Node child in Children)
            {
                yield return child;
            }
        }
    }

Now you can do this to find a particular node by ID:

var idToFind = "2childnode3.txt";

var node = nodes.SelectMany(n => n.DescendantsAndSelf())
                .Where(n => n.Id == idToFind)
                .FirstOrDefault();

if (node != null) 
{
    Console.WriteLine(node.ItsPath);
}
else
{
    Console.WriteLine("Not found");
}

Fiddle: https://dotnetfiddle.net/u9gDTc

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300