1

I have a list of strings that represent hierarchical data and are hyphen-separated (3 hyphens denote separation). I'm trying to convert this list into a JSON string so that I can bind it to a tree control.

I am looking for a C# example.

The list can be as follow (list is not the complete list and in some cases it can have 7 nodes deep, but you can get the idea):

Automotive Electronics
Automotive Electronics---Body Electronics
Automotive Electronics---Body Electronics---Access Control Systems
Automotive Electronics---Body Electronics---Body Control Modules
Automotive Electronics---Driver Information
Automotive Electronics---Driver Information---Clocks
Automotive Electronics---Driver Information---Compass Systems
Automotive Electronics---HomeL
Automotive Electronics---Infotainment & Connectivity
Automotive Electronics---Infotainment & Connectivity---Handsfree Systems
Automotive Interiors
Automotive Interiors---Door Panels
Automotive Interiors---Floor Consoles
Automotive Interiors---Headliners & Overhead Systems
Automotive Interiors---Overhead Consoles
Automotive Seating
Automotive Seating---Complete Seats
Automotive Seating---Complete Seats---SuperThin Seats
gpoo
  • 8,408
  • 3
  • 38
  • 53
TheRedDwarf
  • 183
  • 1
  • 13
  • Will this data change very often? And will you be typing this in or pulling it from another source? – Chazt3n Oct 17 '12 at 19:02
  • it comes from a database, so it has the potential to change... I'm basically pulling these out of the DB as a List – TheRedDwarf Oct 17 '12 at 19:06
  • ok gotcha, will they come in as hierarchical? – Chazt3n Oct 17 '12 at 19:21
  • they will come in exactly as I have the list above.... that is to say, already in order, and the parent will always have come before the child. – TheRedDwarf Oct 17 '12 at 19:25
  • What is your expected output? I assume you would like it in a certain format (which you don't provide here). – Styxxy Oct 17 '12 at 20:13
  • @Styxxy he expects to convert the list into JSON, as it is stated in the question. – gpoo Oct 17 '12 at 20:23
  • Thanks gpoo for trying to answer my question, but you missed my point. There are many, many ways of representing this in JSON, what is it that the TS wants. I assume he has some format in his mind that he wants to have (especially if he wants to bind it to a listview, then probably it is handy if you have some format you want to work towards). – Styxxy Oct 17 '12 at 20:27
  • I apologize, as I'm not familiar with JSON to know the different formats. Ultimately, I'm trying to bind this list of hierarchical items to an MVC TreeView control. I was told I could do that with JSON. – TheRedDwarf Oct 17 '12 at 20:35
  • actually, if it makes it easier... XML would work... (?) – TheRedDwarf Oct 17 '12 at 20:46

1 Answers1

0

The main trick is to get the strings into a tree structure. The next code snippet (linqpad) does that. I don't know if the output as-is is something you can handle client-side, but it should be something you can modify as it suits you.

void Main()
{
    var rootNode = new Node("root");
    foreach(string s in new[] {"Automotive Electronics",
        "Automotive Electronics---Body Electronics",
        "Automotive Electronics---Body Electronics---Access Control Systems",
        "Automotive Electronics---Body Electronics---Body Control Modules",
        "Automotive Electronics---Driver Information",
        "Automotive Electronics---Driver Information---Clocks",
        "Automotive Electronics---Driver Information---Compass Systems",
        "Automotive Electronics---HomeL",
        "Automotive Electronics---Infotainment & Connectivity",
        "Automotive Electronics---Infotainment & Connectivity---Handsfree Systems",
        "Automotive Interiors",
        "Automotive Interiors---Door Panels",
        "Automotive Interiors---Floor Consoles",
        "Automotive Interiors---Headliners & Overhead Systems",
        "Automotive Interiors---Overhead Consoles",
        "Automotive Seating",
        "Automotive Seating---Complete Seats",
        "Automotive Seating---Complete Seats---SuperThin Seats"})
    {
        AddNodes(rootNode, s.Split(new[] {"---"}, StringSplitOptions.RemoveEmptyEntries));
    }
    new JavaScriptSerializer().Serialize(rootNode.Nodes).Dump();
}

public void AddNodes( Node parentNode, string[] names)
{
    if (names.Any())
    {
        var node = parentNode.AddNode(names.First());
        AddNodes(node, names.Skip(1).ToArray());
    }
}

public class Node
{
    public Node(string name)
    {
        Name = name;
        Nodes = new List<Node>();
    }

    public Node AddNode(string name)
    {
        if (!this.Nodes.Select(n => n.Name).Contains(name.Trim()))
        {
            //name.Dump(this.Name);
            this.Nodes.Add(new Node(name.Trim()));
        }
        return this.Nodes.Where (n => n.Name == name).First();
    }

    public string Name { get;set;}
    public List<Node> Nodes { get; set; }
}

Output:

[{"Name":"Automotive Electronics","Nodes":[{"Name":"Body Electronics","Nodes":[{"Name":"Access Control Systems","Nodes":[]},{"Name":"Body Control Modules","Nodes":[]}]},{"Name":"Driver Information","Nodes":[{"Name":"Clocks","Nodes":[]},{"Name":"Compass Systems","Nodes":[]}]},{"Name":"HomeL","Nodes":[]},{"Name":"Infotainment & Connectivity","Nodes":[{"Name":"Handsfree Systems","Nodes":[]}]}]},{"Name":"Automotive Interiors","Nodes":[{"Name":"Door Panels","Nodes":[]},{"Name":"Floor Consoles","Nodes":[]},{"Name":"Headliners & Overhead Systems","Nodes":[]},{"Name":"Overhead Consoles","Nodes":[]}]},{"Name":"Automotive Seating","Nodes":[{"Name":"Complete Seats","Nodes":[{"Name":"SuperThin Seats","Nodes":[]}]}]}]

(Note that for the JavaScriptSerializer you have to import some namespaces in linqpad to run this snippet).

Gert Arnold
  • 105,341
  • 31
  • 202
  • 291