ASP.NET - XML to treeview based on ParentId - Asked By asif hameed on 17-May-12 12:17 PM

Earn up to 20 extra points for answering this tough question.
I have an XML like this:

<table name="tblcats">
<row>
        <Id>1741</Id>
        <Industry>Oil &amp; Gas - Integrated</Industry>
        <ParentId>1691</ParentId>
    </row>
    <row>
        <Id>1690</Id>
        <Industry>Commodities</Industry>
        <ParentId>1691</ParentId>
    </row>
    <row>
        <Id>1691</Id>
        <Industry>Capital Goods</Industry>
        <ParentId>0</ParentId>
    </row>
</table>


I want to create a Treeview from this XML so that table is parent node and then nodes ParentId 0 is second parent and then child nodes with Parent Id greater than 0


Like this:


+Table +Capital Goods Commodities Oil & Gas - Integrated


How can I do this? Please suggest


Regards, Asif Hameed

[)ia6l0 iii replied to asif hameed on 17-May-12 10:33 PM
Can you modify the xml such that the parent-child relationships exist in the xml itself? If yes, then that is the easiest way out. 

<table name="tblcats">
<row>
    <row>
    <Id>1691</Id>
    <Industry>Capital Goods</Industry>
    <ParentId>0</ParentId>
      <row><Id>1741</Id>
        <Industry>Oil &amp; Gas - Integrated</Industry>
        <ParentId>1691</ParentId>
      </row>
      <row>
        <Id>1690</Id>
        <Industry>Commodities</Industry>
        <ParentId>1691</ParentId>
      </row>
     </row>
</table>

If you change it this way, you can load this xml into a dataset, and it will build the relationships (parent-child) for you. Then you could loop over the parents and build the main node, and each nodes under the parent to build the child nodes. 

If not, please use XPath queries to determine the parent-child and build the nodes collection. 

Hope this helps.
Jitendra Faye replied to asif hameed on 18-May-12 12:14 AM
Follow these links-

http://www.codeproject.com/Articles/12606/Loading-and-Saving-XML-to-and-from-a-TreeView-Cont
http://www.codeproject.com/Articles/13099/Loading-and-Saving-a-TreeView-control-to-an-XML-fi
http://www.java2s.com/Code/CSharp/XML/DisplayXMLfilecontenttoTreeView.htm


Here you will get some idea about filling xml to treeview.
Somesh Yadav replied to asif hameed on 18-May-12 12:55 AM

A fairly simplistic approach would be to use the standard ASP.NET controls XmlDataSource and TreeView and use an XSLT transform file to transform the XML you have into something that the TreeView control likes.

So, assuming you have the XML above in a file called cats.xml, the ASP.NET page markup would look like:

<asp:XmlDataSource ID="CatsXml" runat="server" DataFile="~/cats.xml" TransformFile="~/cats.xslt"></asp:XmlDataSource>
<asp:TreeView ID="CatsTree" runat="server" DataSourceID="CatsXml">
   
<DataBindings><asp:TreeNodeBinding TextField="name" ValueField="id" /></DataBindings>
</asp:TreeView>

and the XSLT file (cats.xslt) would be:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
 
<xsl:output method="xml" indent="yes"/>

 
<xsl:template match="table">
   
<table id="-1" name="Table">
     
<xsl:for-each select="/table/row[ParentId = 0]">
       
<industry>
         
<xsl:attribute name="id">
           
<xsl:value-of select="Id"/>
         
</xsl:attribute>
         
<xsl:attribute name="name">
           
<xsl:value-of select="Industry"/>
         
</xsl:attribute>
         
<xsl:call-template name="industry-template">
           
<xsl:with-param name="pId" select="Id" />
         
</xsl:call-template>
       
</industry>
     
</xsl:for-each>
   
</table>
 
</xsl:template>

 
<xsl:template name="industry-template">
   
<xsl:param name="pId" />
   
<xsl:for-each select="/table/row[ParentId = $pId]">
     
<industry>
       
<xsl:attribute name="id">
         
<xsl:value-of select="Id"/>
       
</xsl:attribute>
       
<xsl:attribute name="name">
         
<xsl:value-of select="Industry"/>
       
</xsl:attribute>
       
<xsl:call-template name="industry-template">
Chintan Vaghela replied to asif hameed on 18-May-12 05:49 AM

Hello,

 

First  load xml file to XMLDocuemnt.

After fill DataSet through XMLDocument.

Now for loop through each table in DataSet.

Get row table and get into DefaultView for sorting ParentID

So PatentID = 0 is getting first.

After then forloop through added node in Treeview

 

Try following code to Bind TreeView

 

 

 

public void BindXMLData(string path)

    {

      trvXmlData.Nodes.Clear();

      if (File.Exists(path))

      {

        FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

        System.Xml.XmlDocument doc = new System.Xml.XmlDocument();

        doc.Load(fs);

        using (DataSet ds = new DataSet())

        {

          ds.ReadXml(new XmlNodeReader(doc));

          TreeNode ParentNode = new TreeNode();

          foreach (DataTable tab in ds.Tables)

          {

            if (tab.TableName == "table")

            {

              ParentNode.Text = tab.TableName;

              trvXmlData.Nodes.Add(ParentNode);

            }

            else

            {

              DataView dv = tab.DefaultView;

              //apply the sort on CustomerSurname column 

              dv.Sort = "ParentId,Id";

              //save our newly ordered results back into our datatable 

              DataTable tab1 = dv.ToTable(true, "Industry", "ParentId");

              TreeNode ChileLevel1Node = new TreeNode();

              foreach (DataRow row in tab1.Rows)

              {

                if (row["ParentID"].ToString() == "0")

                {

                  ChileLevel1Node.Text = row["Industry"].ToString();

                  ParentNode.ChildNodes.Add(ChileLevel1Node);

                }

                else

                {

                  TreeNode ChildNode = new TreeNode(row["Industry"].ToString());

                  ChileLevel1Node.ChildNodes.Add(ChildNode);

 

                }

              }

            }

          }

          fs.Close();

        }

      }

    }

Note :: There is no need to modify XML file.

 

Hope this helpful!

 

Happy Coding J

Thanks

 

 

 

 

kalpana aparnathi replied to asif hameed on 20-May-12 06:45 AM
hi,

You can try to use the XMLDocument object for reading the xml file content. then you can bind the users relationship by the user relative property.

http://msdn.microsoft.com/es-es/library/system.xml.xmldocument.aspx

By the way, you can use the DataSet object to load the XML file content to DataSet object, then bind the data to your tree control. and you need to check the data relationship.

http://msdn.microsoft.com/en-us/library/84sxtbxh(VS.71).aspx  

Regards,
Reena Jain replied to asif hameed on 21-May-12 04:21 AM
Hi,

I always use following method to bind the xml with tree view. I will suggest one more option of sitemap. Here is a simple way you can create a Treeview from XMLDataSource

Create a XMLDataSource for example

<?xml version="1.0" encoding="utf-8" ?> 
<ToolBox
  <Item Name="Standard Toolbox Controls"
  <Option Control="AdRotator" /> 
  <Option Control="BulletedList" /> 
  <Option Control="CheckBox" /> 
  <Option Control="FileUpload" /> 
  <Option Control="MultiView" /> 
  </Item
  <Item Name="Data Toolbox Controls"
  <Option Control="ListView" /> 
  <Option Control="GridView" /> 
  <Option Control="LinqDataSource" /> 
  <Option Control="XmlDataSource" /> 
  </Item> </ToolBox

Now place a treeview in your ASPX page and pass the datasourceID property of Treeview Control to XML datasoruce like below

<div
  <asp:XmlDataSource ID="XmlDataSource1" runat="server" DataFile="~/App_Data/AspNetControls.xml"
  </asp:XmlDataSource
  <asp:TreeView ID="TreeView1" runat="server" DataSourceID="XmlDataSource1"
  <DataBindings
  <asp:TreeNodeBinding DataMember="ToolBox" Text="Asp.Net ToolBox" /> 
  <asp:TreeNodeBinding DataMember="Item" TextField="Name" /> 
  <asp:TreeNodeBinding DataMember="Option" TextField="Control" /> 
  </DataBindings
  </asp:TreeView
  </div>

Hope this will help you