c#解析xml绑定treeview控件实现

原创 2014年09月14日 21:58:48

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="white-space:pre">	</span>向web端的api发送http请求,得到的结果是xml格式的节点信息,id标识节点号,pid标识该节点的父节点(0表示根),name是名字。</span>

节点信息本来是web端通过dfs得到的。

原本的思路是:根据xml节点,解析它,构建邻接矩阵或者邻接表,用dfs(先序,遍历到就添加到treeview里去)生成treeview,c语言做算法实现比较好搞,c#水平有限,毕竟google没了,自己baidu做项目 = = 

换了个思路,因为api得到的xml节点顺序正好是dfs得到的,因此我只要根据这个顺序建立节点绝对没问题,因为每个节点插入进去,绝对能够找到父节点!

有思路了,直接开撸。

附上xml:

<content>
	<item>
		<id>1</id>
		<pid>0</pid>
		<name>5YiG57G7MQ==</name>
	</item>
	<item>
		<id>2</id>
		<pid>1</pid>
		<name>5YiG57G7MS0x</name>
	</item>
	<item>
		<id>3</id>
		<pid>2</pid>
		<name>5YiG57G7MS0xLTE=</name>
	</item>
	<item>
		<id>4</id>
		<pid>2</pid>
		<name>5YiG57G7MS0xLTI=</name>
	</item>
	<item>
		<id>5</id>
		<pid>1</pid>
		<name>5YiG57G7MS0y</name>
	</item>
	<item>
		<id>6</id>
		<pid>0</pid>
		<name>5YiG57G7Mg==</name>
	</item>
	<item>
		<id>9</id>
		<pid>6</pid>
		<name>5YiG57G7Mi0x</name>
	</item>
</content>

name是用base64编码过的结果,取出来解码就可以。

使用了一个类来定义xml的节点,便于还原节点。

附上treeNode的定义:


public class TreesNode
        {
            public TreesNode parent;

            private int id; //当前节点id

            public int Id
            {
                get { return id; }
                set { id = value; }
            }

            private int pid; //父节点 0表示根

            public int Pid
            {
                get { return pid; }
                set { pid = value; }
            }

            public string name = null;
 
            public TreesNode(int id, int pid, string name)
            {
                this.id = id;
                this.pid = pid;
                this.name = TreesNode.decriptionBase64(name); 
            }

            public static string decriptionBase64(string oralName)
            {
                byte[] outputb = Convert.FromBase64String(oralName); //base64解码           
                string resultName = Encoding.GetEncoding("utf-8").GetString(outputb);
                return resultName; 
            }
        }

然后是解析xml生成treeNode数组的过程,解析的时候注意逻辑就好

/// <summary>
        /// 解析xml 生成dfs需要的数组
        /// </summary>
        /// <param name="xmlFile"></param>
        public void translateXML(string xmlFile)
        {
            int id, pid,temp;
            string name;

            XmlDocument doc = new XmlDocument();   
            doc.Load(xmlFile);   //加载Xml文件  
            XmlElement rootElem = doc.DocumentElement;   //获取根节点  
            XmlNodeList itemNodes = rootElem.GetElementsByTagName("item"); //获取item子节点集合  

            //根节点先进去
            ITAMngApp.TkMng.UpLoadForm.TreeDefinition.TreesNode firstOne = new ITAMngApp.TkMng.UpLoadForm.TreeDefinition.TreesNode(0, 0, "5pyN5Yqh5Zmo");  //服务器
            firstOne.parent = null;
            actualTreeNodes[0] = firstOne;
            countActualTreeNodes++;

            //之后所有的item节点根据xml放进数组中去
            foreach (XmlNode node in itemNodes)
            {
                //读取item下的id pid name

                XmlNodeList subAgeNodes = ((XmlElement)node).GetElementsByTagName("id");

                if (int.TryParse(subAgeNodes[0].InnerText, out temp) == true)
                {
                    id = temp;
                    subAgeNodes = ((XmlElement)node).GetElementsByTagName("pid");
                    if (int.TryParse(subAgeNodes[0].InnerText, out temp) == true) 
                    {
                        pid = temp;
                        subAgeNodes = ((XmlElement)node).GetElementsByTagName("name");
                        name = subAgeNodes[0].InnerText;
                        //ok!!!!生成数组!!!! 节点的顺序就是web端dfs得到的,
                        //根据 id 确定存放在 actualTreeNode 数组的位置,通过每个对象的 pid 属性来确定添加到对应的 treeview 节点下
                        ITAMngApp.TkMng.UpLoadForm.TreeDefinition.TreesNode tempNode = new ITAMngApp.TkMng.UpLoadForm.TreeDefinition.TreesNode(id, pid, name);
                        tempNode.parent = actualTreeNodes[pid];
                        actualTreeNodes[id] = tempNode;
                        if( tempNode.Id > countActualTreeNodes )
                        {
                            countActualTreeNodes = tempNode.Id;
                        }
                    }      
                }
          

用了数组来保存解析的node并且计数方便读取。

 //存放xml读取出来的treenode节点,先从xml读取出来生成数组,然后treeview根据每个节点的father为treeview来add节点
        private ITAMngApp.TkMng.UpLoadForm.TreeDefinition.TreesNode[] actualTreeNodes = new ITAMngApp.TkMng.UpLoadForm.TreeDefinition.TreesNode[50];

        //计数
        private int countActualTreeNodes = 0;


然后生成treeview即可,思路:

根据actualTreeNodes数组,添加每个节点到treeview,根据name遍历寻找父亲节(xml是dfs得到所以父亲)点然后添加(拿name遍历数组即可

/// <summary>
        /// 解析xml 生成dfs需要的数组
        /// </summary>
        /// <param name="xmlFile"></param>
        public void translateXML(string xmlFile)
        {
            int id, pid,temp;
            string name;

            XmlDocument doc = new XmlDocument();   
            doc.Load(xmlFile);   //加载Xml文件  
            XmlElement rootElem = doc.DocumentElement;   //获取根节点  
            XmlNodeList itemNodes = rootElem.GetElementsByTagName("item"); //获取item子节点集合  

            //根节点先进去
            ITAMngApp.TkMng.UpLoadForm.TreeDefinition.TreesNode firstOne = new ITAMngApp.TkMng.UpLoadForm.TreeDefinition.TreesNode(0, 0, "5pyN5Yqh5Zmo");  //服务器
            firstOne.parent = null;
            actualTreeNodes[0] = firstOne;
            countActualTreeNodes++;

            //之后所有的item节点根据xml放进数组中去
            foreach (XmlNode node in itemNodes)
            {
                //读取item下的id pid name

                XmlNodeList subAgeNodes = ((XmlElement)node).GetElementsByTagName("id");

                if (int.TryParse(subAgeNodes[0].InnerText, out temp) == true)
                {
                    id = temp;
                    subAgeNodes = ((XmlElement)node).GetElementsByTagName("pid");
                    if (int.TryParse(subAgeNodes[0].InnerText, out temp) == true) 
                    {
                        pid = temp;
                        subAgeNodes = ((XmlElement)node).GetElementsByTagName("name");
                        name = subAgeNodes[0].InnerText;
                        //ok!!!!生成数组!!!! 节点的顺序就是web端dfs得到的,
                        //根据 id 确定存放在 actualTreeNode 数组的位置,通过每个对象的 pid 属性来确定添加到对应的 treeview 节点下
                        ITAMngApp.TkMng.UpLoadForm.TreeDefinition.TreesNode tempNode = new ITAMngApp.TkMng.UpLoadForm.TreeDefinition.TreesNode(id, pid, name);
                        tempNode.parent = actualTreeNodes[pid];
                        actualTreeNodes[id] = tempNode;
                        if( tempNode.Id > countActualTreeNodes )
                        {
                            countActualTreeNodes = tempNode.Id;
                        }
                    }      
                }
            }
        }

        /// <summary>
        /// 根据actualTreeNodes数组,添加每个节点到treeview,根据name遍历寻找父亲节点然后添加(拿name遍历数组即可)
        /// </summary>
        public void addTreeViewNode() 
        {         
            treeViewNode.Nodes.Clear();
            treeViewNode.Nodes.Add(new TreeNode("服务器"));     //根节点加入treeview

            for (int i = 1; i <= countActualTreeNodes; i++)
            {
                //取得当前节点 遍历以前的所有节点找它的父节点,然后添加到父节点下面去!
                //遍历所有treeview中的节点,寻找当前节点的父节点,插入treeview中去(根据dfs的结果,父节点一定存在)

                //currentNode为当前需要插入节点,遍历treeviewNode中所有节点,寻找它的父亲,插入父亲下面!父亲一定存在! 
                ITAMngApp.TkMng.UpLoadForm.TreeDefinition.TreesNode currentNode = actualTreeNodes[i];

                //更新bool
                //finish = false;

                if (currentNode == null)
                {
                    continue;
                }
                foreach (TreeNode item in treeViewNode.Nodes)
                {
                    // item是当前节点,这里是遍历所有treeview节点,找出actual[i]的父亲,然后插入i
                    TreeNode node = GetNode(item, i);   
                    if (currentNode.parent.name == node.Text )
                    {
                        Console.WriteLine("fuck1");
                        TreeNode tempInsertOne = new TreeNode(currentNode.name);
                        treeViewNode.SelectedNode = node;                                  
                        treeViewNode.SelectedNode.Nodes.Add(tempInsertOne);

                        //node.Nodes.Add(tempInsertOne);                                    //这个add这里有问题!
                        //finish = true;
                        break;
                    }
                    else
                    {
                        continue;
                    }
                }
            }
            treeViewNode.CollapseAll();
        }

        //遍历子节点
        public TreeNode GetNode(TreeNode currentRoot, int currentNumber)
        {    
            if (currentRoot.Nodes.Count == 0)     //如果是根,返回  
            {
                Console.WriteLine("fuck3");
                //return currentRoot.Nodes[0];
                return treeViewNode.TopNode;   //返回定点 只会执行一次
            }
            else if (treeViewNode.Nodes.Count != 0)     //非根节点
            {
                Console.WriteLine("fuck4");
                TreeNode[] treeNodes = treeViewNode.Nodes.Find(currentRoot.Name, true);  //可以返回所有以currentRoot.test为标识的节点
                foreach (TreeNode temp in treeNodes)
                {
                    if (actualTreeNodes[currentNumber].parent.name == temp.Text)
                    {
                        return temp;
                        //temp.Nodes.Add(new TreeNode(actualTreeNodes[currentNumber].name));
                    }
                }
            }
            return currentRoot;
        }

        /// <summary>
        /// TreeViewNode点击事件相应
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeViewNode_AfterSelect(object sender, TreeViewEventArgs e)
        {
            string messageAfterSelect = string.Format("选中了{0}节点\n\n深度{1}的节点", treeViewNode.SelectedNode.Text, treeViewNode.SelectedNode.Level);
            MessageBox.Show(messageAfterSelect, "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
        }

成功绑定treeview!附上效果图:

treeviewShow

















版权声明:本文为博主原创文章,未经博主允许不得转载。

C#TreeView读取Xml,TreeView导出到Xml

实现功能有 1.根据Xml生成TreeView 2.双击修改节点 3.右键添加子节点或添加要节点 4.右键删除当前选择的节点 5.将修改后的TreeView重新生成Xml文档 源码下载  ...

winform实现 绑定xml文档到treeview 控件

窗体类代码: using System; using System.Collections.Generic; using System.ComponentModel; using System...
  • sfcyyc
  • sfcyyc
  • 2012年04月11日 10:28
  • 3850

c#如何实现从xml中加载树目录,并且显示完整的Text

谈到xml,相信有一定编程基础的童鞋们都比较清楚了。xml文件格式类似于嵌套的样式,这种独特的层次结构很容易使我们联想到目录树,因此这不禁让我们对两者之间产生一种牵线的想法。这不禁,使我们有这么一个问...
  • ztzi321
  • ztzi321
  • 2015年03月05日 08:35
  • 2263

C#TreeView控件与XML相关操作

在C#的应用开发中,TreeView控件是一种比较常用的控件,主要反映了父子节点之间的关系,由于TreeView控件与XML文件的组织结构比较类似,可以把TreeView控件与XML文件结合使用。Tr...

C#打开xml,并绑定TreeView

XML读取与写入  这个代码有个问题就是XML一个节点的属性 xNode.Attributes不能显示出来   //加载XML文件,并在TreeView上显示         publi...

c# comboBox 使用 linq to xml 绑定 XML文件

c# comboBox 使用 linq 绑定数据源 (XML文件)

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

C#用 XML 绑定多个ComboBox

0 绑定第一个ComboBox private void Mxdr_Form_Load(object sender, EventArgs e) { ...

C#中对XML文档的操作(增改删,绑定到GridView)

可扩展标记语言 ( XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 XML非常适合 Web 传输。XML 提供统...
  • gxwzmm
  • gxwzmm
  • 2013年02月08日 13:07
  • 3666

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:c#解析xml绑定treeview控件实现
举报原因:
原因补充:

(最多只允许输入30个字)