locked
Populate Windows Forms TreeView from XML file

    Question

  • Is this [How to populate a TreeView control with XML data in Visual C# 2005 or in Visual C# .NET] still the best way to populate a TreeView control from XML, or is there a better way with LINQ?

     

    I have a TreeView that I am trying to populate from this XML file:

     

    <?xml version="1.0"?>
    <CATALOG GREENHOUSE="Bonnie May">
      <PLANT>
        <COMMON>Bloodroot</COMMON>
        <BOTANICAL>Sanguinaria canadensis</BOTANICAL>
        <ZONE>4</ZONE>
        <LIGHT>Mostly Shady</LIGHT>
        <PRICE>$2.44</PRICE>
        <AVAILABILITY>031599</AVAILABILITY>
      </PLANT>
      <PLANT>
        <COMMON>Columbine</COMMON>
        <BOTANICAL>Aquilegia canadensis</BOTANICAL>
        <ZONE>3</ZONE>
        <LIGHT>Mostly Shady</LIGHT>
        <PRICE>$9.37</PRICE>
        <AVAILABILITY>030699</AVAILABILITY>
      </PLANT>

    </CATALOG>

     

    I am able to pull the GREENHOUSE attribute and set this as my TreeView ROOT, now I would like to set the value of the child nodes as the values from CATALOG > PLANT > COMMON in the TreeView

     

    Code Snippet

    private void Form1_Load(object sender, EventArgs e)
            {
                    XDocument data = XDocument.Load(@"c:\plant_catalog.xml");
                    treeView1.Nodes.Clear();
                    TreeNode node = treeView1.Nodes.Add(data.Root.Attribute("GREENHOUSE").Value);
                    // TODO create child nodes
            }

     

     

    Monday, July 21, 2008 6:38 PM

Answers

  • Got it! I don't know if this is the best way to do it, but here is my completed code:

     

     

    Code Snippet

    private void Form1_Load(object sender, EventArgs e)

    {

    XDocument data = XDocument.Load(@"c:\plant_catalog.xml");

    TreeNode node = treeView1.Nodes.Add(data.Element("CATALOG").Element("GREENHOUSE").Value);

    IEnumerable<XElement> items = from el in data.Descendants("COMMON")

    select el;

    foreach (XElement pltName in items)

    node.Nodes.Add(pltName.Value);

    }

     

     

    I also altered the XML file by making the GREENHOUSE attribute an element, though it could have been left as an attribute with a very minor code edit.
    Tuesday, July 22, 2008 10:26 PM

All replies

  • Got it! I don't know if this is the best way to do it, but here is my completed code:

     

     

    Code Snippet

    private void Form1_Load(object sender, EventArgs e)

    {

    XDocument data = XDocument.Load(@"c:\plant_catalog.xml");

    TreeNode node = treeView1.Nodes.Add(data.Element("CATALOG").Element("GREENHOUSE").Value);

    IEnumerable<XElement> items = from el in data.Descendants("COMMON")

    select el;

    foreach (XElement pltName in items)

    node.Nodes.Add(pltName.Value);

    }

     

     

    I also altered the XML file by making the GREENHOUSE attribute an element, though it could have been left as an attribute with a very minor code edit.
    Tuesday, July 22, 2008 10:26 PM
  • There is a more generic method than having a foreach loop for each level of the XML.  I created a Recursive function that used LINQ, since I'm using LINQ for creating the XML too...  Here's the function. 

            private TreeNode CreateTreeFromXML(XElement el)
            {
                if (el.Elements().Count() == 0)
                {
                    return new TreeNode(el.Name.ToString() + ": " + el.Value);
                }
                else
                {
                    return new TreeNode(el.Name.ToString(),
                        (from child in el.Elements()
                         select CreateTreeFromXML(child)).ToArray());
                }
            }
    

    This way, no matter how large or small the XML is, and no matter how many levels you have to deal with, you're golden.  Your Form Loader is very simple using this:

    private void Form1_Load(object sender, EventArgs e)
            {
                    XDocument data = XDocument.Load(@"c:\plant_catalog.xml");
                    treeView1.Nodes.Clear();
                    treeView1.Nodes.Add(CreateTreeFromXML(data.Root);
                    // TODO create child nodes
            }
    
    

    Thursday, July 16, 2009 2:36 PM