views:

60

answers:

2

Hello Everyone,

I'm very new to xml so I hope I'm not asking any silly question here. I'm currently working on populating a treeview from an XML file that is not hierarchically structured. In the xml file that I was given the child and parent nodes are defined within the attributes of the item element. How would I be able to utilize the attributes in order for the treeview to populate in the right hierarchical order. (Example Mary Jane should be a child node of Peter Smith). At present all names are under one another.

root

<item parent_id="0" id="1"><content><name>Peter Smith</name></content></item>
<item parent_id="1" id="2"><content><name>Mary Jane</name></content></item>
<item parent_id="1" id="7"><content><name>Lucy Lu</name></content></item>
<item parent_id="2" id="3"><content><name>Informatics Team</name></content></item>
<item parent_id="3" id="4"><content><name>Sandy Chu</name></content></item>
<item parent_id="4" id="5"><content><name>John Smith</name></content></item>
<item parent_id="5" id="6"><content><name>Jane Smith</name></content></item>

/root

Thank you for all of your help, Marina

A: 

One possible algorithm is this: 1) Get the list of parent_id nodes as a unique collection (remember to remove duplicates from all collections)

2) Get the id attributes in a collection

3) Create a new empty 'parents' collection

4)For each item in id collection, if corresponding item exists in the parent_id collection, then that item is a parent of some other item. You add this id to the new parents collection that you created

5) After you have a list of parents, bind that to the tree. That is your top level tree elements.

6) After this, you can go through the id collection again and just add each item to its parent using the parent_id attribute

Do realize that this is not the most efficient implementation because you are iterating over the collections a few times instead of doing everything in just one pass (the algorithm for which will certainly be different). So if the collections are small, then the above is a good approach. But it you have tens of thousands of items, going through the collections multiple times may be bad for performance. But this approach is quick and simple to implement. So keep in mind the trade-off.

Also since you are only reading through the XML and not manipulating it, prefer XMLReader class over XMLDocument.

desigeek
Hi, Thank you for the above suggestion. The list is fairly small so I will try and implement the above. Thanks again,Marina
Marina
+1  A: 

Here is a solution using Linq to XML:

    string strXML = @"<root>
        <item parent_id='0' id='1'><content><name>Peter Smith</name></content></item>
        <item parent_id='1' id='2'><content><name>Mary Jane</name></content></item>
        <item parent_id='1' id='7'><content><name>Lucy Lu</name></content></item>
        <item parent_id='2' id='3'><content><name>Informatics Team</name></content></item>
        <item parent_id='3' id='4'><content><name>Sandy Chu</name></content></item>
        <item parent_id='4' id='5'><content><name>John Smith</name></content></item>
        <item parent_id='5' id='6'><content><name>Jane Smith</name></content></item>
        </root>";

    XDocument xDoc = XDocument.Parse(strXML, LoadOptions.None);

    var objData = xDoc.Root.Elements("item").ToList().Select(item =>
        new { id = item.Attribute("id").Value,
              pid = item.Attribute("parent_id").Value,
              tn = new TreeNode(item.Element("content").Element("name").Value)
        }).ToList();

    objData.ForEach(child =>
        {
            var parent = objData.FirstOrDefault(m => m.id == child.pid);
            if (parent != null)
                parent.tn.Nodes.Add(child.tn);
        });
    // Add all nodes with no parent to the TreeView's root:
    objData.Where(n => n.tn.Parent == null).ToList().ForEach(n => treeView1.Nodes.Add(n.tn));
Simon Chadwick
Hi Simon,Thank you for the code. I have tried to add this although it's not picking up the parent.tn.Nodes.Add(child.tn) properly. Would you have an idea as to why (Specifically the "Nodes")?The error states that it is a method which is not valid in the given context.Much appreciation!Marina
Marina
Hi Marina, It could be that your project is missing a reference to System.Windows.Forms.dll, or a using statement. If it helps my VS 2010 solution is temporarily at http://www.simonchadwick.com/Transfer/WindowsFormsApplication2.zip. Best wishes!
Simon Chadwick
Hi Simon,You were right, it was the reference. Thank you for the solution it's quite helpful!!Very Best,Marina
Marina
Hi Marina, Glad I could help. Please consider marking the answer accepted, possibly with an upvote.
Simon Chadwick