从XML填充树视图

时间:2011-12-14 11:11:11

标签: c# xml treeview treenode

我目前正在尝试从Web请求中返回给我的xml填充树视图。当响应进来时,我正在操纵数据,以便XML处于这种布局中:

<GroupList>
    <Group>
        <GroupName>my first test group</GroupName>
        <GroupID>djnsldgnljsdngljsdngljns</GroupID>
        <AccessLevel>high</AccessLevel>
        <SubGroup>
            <SubGroupName>my first test subgroup</SubGroupName>
            <SubGroupID>djnsldgnljsdngljsdngljns</SubGroupID>
        </SubGroup>
    </Group>
    <Group>
        <GroupName>my second test group</GroupName>
        <GroupID>djnsldgnljsdngljsdngl</GroupID>
        <AccessLevel>high</AccessLevel>
        <SubGroup>
            <SubGroupName>my second test subgroup</SubGroupName>
            <SubGroupID>DBXRdjnsldgnljsdngljsdngl</SubGroupID>
        </SubGroup>
        <SubGroup>
            <SubGroupName>my second test subgroup1</SubGroupName>
            <SubGroupID>EJdjnsldgnljsdngljsdngl42</SubGroupID>
        </SubGroup>
    </Group>
</GroupList>

我想要做的就是显示groupName,然后您就可以展开和查看子组了。目前我已经让它“有点”工作,但它在一个线性视图中。这是我目前的代码:

  xmlDoc.LoadXml(response2);

  groupsTreeView.Nodes.Clear();
  groupsTreeView.Nodes.Add(new
  TreeNode(xmlDoc.DocumentElement.InnerText));
  TreeNode tNode = new TreeNode();
  tNode = (TreeNode)groupsTreeView.Nodes[0];

  addTreeNode(xmlDoc.DocumentElement, tNode);

  groupsTreeView.ExpandAll();

//This function is called recursively until all nodes are loaded
    private void addTreeNode(XmlNode xmlNode, TreeNode treeNode)
    {
        XmlNode xNode;
        TreeNode tNode;
        XmlNodeList xNodeList;
        if (xmlNode.HasChildNodes) //The current node has children
        {
            xNodeList = xmlNode.ChildNodes;

            for (int x = 0; x <= xNodeList.Count - 1; x++)
            //Loop through the child nodes
            {
                xNode = xmlNode.ChildNodes[x];
                groupsTreeView.Nodes.Add(new TreeNode(xNode.Value));
                tNode = groupsTreeView.Nodes[x];
                addTreeNode(xNode, tNode);
            }
        }
        else //No children, so add the outer xml (trimming off whitespace)
            treeNode.Text = xmlNode.OuterXml.Trim();
    }

此图像是在我的系统本地浏览时上面的代码:

enter image description here

任何建议,我都很失落,它正在努力!

4 个答案:

答案 0 :(得分:2)

您可以尝试使用linq xml(System.Xml.Linq):

    private TreeNode TNGroups(XElement xml)
    {
        TreeNode node = new TreeNode();
        foreach (XElement group in xml.Descendants("Group"))
        {
            TreeNode tnGroup = new TreeNode(group.Element("GroupName").Value);
            node.Nodes.Add(tnGroup);
            foreach (XElement subgroup in group.Elements("SubGroup"))
            {
                TreeNode tnSubGroup = new TreeNode(subgroup.Element("SubGroupName").Value);
                tnGroup.Nodes.Add(tnSubGroup);
            }
        }
        return node;
    }

您可以将其称为myTreeView.Nodes.Add(TNGroups(groupsXML))

要将XML加载到元素中,只需使用XElement.Load

答案 1 :(得分:1)

我需要类似的东西。我喜欢bferrer的答案中的属性添加,所以我修改了它并把它放在一个类中:

using System;
using System.Text;
using System.Xml;
using System.Drawing;
using System.Windows.Forms;

namespace TreeViewTest
{
    class XmlTreeViewBuilder
    {
        private XmlDocument xDoc;
        private TreeView tView;

        //Constructor with parameters
        public XmlTreeViewBuilder(XmlDocument xDocument, TreeView treeView)
        {
            this.xDoc = xDocument;
            this.tView = treeView;
        }

        public void getTreeView()
        {
            tView.Nodes.Clear();                                        //Clear out the nodes before building
            XmlNode pNode = xDoc.DocumentElement;                       //Set the xml parent node = xml document element
            string Key = pNode.Name == null ? "" : pNode.Name;          //If null set to empty string, else set to name
            string Value = pNode.Value == null ? Key : pNode.Value;     //If null set to node name, else set to value
            TreeNode tNode = tView.Nodes.Add(Key, Value);               //Add the node to the Treeview, set tNode to that node
            AddTreeNodes(pNode, tNode);                                 //Call the recursive function to build the tree
        }

        //Build out the tree recursively
        private void AddTreeNodes(XmlNode currentParentNode, TreeNode currentTreeNode)
        {
            //Check to see if the node has attributes, if so add them
            if (currentParentNode.Attributes != null && currentParentNode.Attributes.Count > 0)
            {
                foreach (XmlAttribute attrib in currentParentNode.Attributes)
                {
                    //Create a node for the attribute name
                    TreeNode attribNode = new TreeNode();
                    attribNode.Name = attrib.Name;
                    attribNode.ForeColor = Color.Red;
                    attribNode.Text = "<Attribute>:" + attrib.Name;
                    //treeNode adds the attribute node
                    currentTreeNode.Nodes.Add(attribNode);

                    //Create a node for the attribute value
                    TreeNode attribValue = new TreeNode();
                    attribValue.Name = attrib.Name;
                    attribValue.ForeColor = Color.Blue;
                    attribValue.Text = attrib.Value;
                    //Attribute node adds the value node
                    attribNode.Nodes.Add(attribValue);
                }
            }
            //Recursively add children, grandchildren, etc...
            if (currentParentNode.HasChildNodes)
            {
                foreach (XmlNode childNode in currentParentNode.ChildNodes)
                {
                    string Key = childNode.Name == null ? "" : childNode.Name;
                    string Value = childNode.Value == null ? Key : childNode.Value;
                    TreeNode treeNode = currentTreeNode.Nodes.Add(Key, Value);
                    //Recursive call to repeat the process for all child nodes which may be parents
                    AddTreeNodes(childNode, treeNode);
                }
            }
        }

    }
}

现在从我的表单中我只需要实例化一个对象并像这样调用getTreeView():

        XmlTreeViewBuilder tBuilder = new XmlTreeViewBuilder(xmlDoc, treeView1);
        tBuilder.getTreeView();

我可以根据需要向类中添加更多函数,例如:getNode,setNode等。希望这可以帮助某人。

答案 2 :(得分:0)

您正在使用递归来遍历Xml文件,遗憾的是您在每次迭代时都将Treenode添加到Treeview的根目录中。相反,修改代码以将子节点添加到循环中正在处理的treenode,例如

for (int x = 0; x <= xNodeList.Count - 1; x++)
    //Loop through the child nodes
    {
        xNode = xmlNode.ChildNodes[x];
        // Use the treenode, not the treeview!!!
        treeNode.Nodes.Add(new TreeNode(xNode.Value));
        tNode = groupsTreeView.Nodes[x];
        addTreeNode(xNode, tNode);
    }

答案 3 :(得分:0)

我使用了你的回答代码,并得到了一些带有属性和复杂结构的XML错失显示。混合你所有的想法得到了这个。好像对某人有用

   private void populateBaseNodes(XmlDocument docXML)
    {
        tView.Nodes.Clear(); // Clear
        tView.BeginUpdate();
        TreeNode treenode;

        XmlNodeList baseNodeList = docXML.ChildNodes;

        foreach (XmlNode xmlnode in baseNodeList)
        {
            string key = xmlnode.Name == null ? "" : xmlnode.Name.ToString();
            string value = xmlnode.Value == null ? xmlnode.Name.ToString() : xmlnode.Value.ToString();
            treenode = tView.Nodes.Add(key, value); // add it to the tree

            if (xmlnode.Attributes.Count > 0)
            {
                foreach (XmlAttribute att in xmlnode.Attributes)
                {
                    TreeNode tnode = new TreeNode();
                    string _name = att.Name;
                    string _value = att.Value.ToString();
                    tnode.Name= _name;
                    tnode.ForeColor = Color.Red;
                    tnode.Text= "<Attribute>:" +_name;
                    TreeNode _attvalue = new TreeNode();
                    _attvalue.Name = _name;
                    _attvalue.Text = _value;
                    _attvalue.ForeColor = Color.Purple;
                    tnode.Nodes.Add(_attvalue);
                    treenode.Nodes.Add(tnode);
                }
            }
            AddChildNodes(xmlnode, treenode);
        }
        tView.EndUpdate();
        tView.Refresh();
    }

    private void AddChildNodes(XmlNode nodeact, TreeNode TreeNodeAct)
    {
        XmlNodeList ChildNodeList = nodeact.ChildNodes;
        TreeNode aux = null;

        if (nodeact.HasChildNodes)
        {
            //Recursive Call
            foreach (XmlNode xmlChildnode in nodeact.ChildNodes)
            {
                //Add Actual Node & Properties
                string Key = xmlChildnode.Name == null ? "" : xmlChildnode.Name.ToString();
                string Value = xmlChildnode.Value == null ? xmlChildnode.Name.ToString() : xmlChildnode.Value.ToString();

                aux = TreeNodeAct.Nodes.Add(Key, Value);
                AddChildNodes(xmlChildnode, aux);

                if (xmlChildnode.Attributes != null && xmlChildnode.Attributes.Count > 0)
                {
                    foreach (XmlAttribute att in xmlChildnode.Attributes)
                    {
                        TreeNode tnode = new TreeNode();
                        string _name = att.Name;
                        string _value = att.Value.ToString();
                        tnode.Name = _name;
                        tnode.Text = "<Attribute>:" + _name;
                        tnode.ForeColor = Color.Red;
                        tnode.Text = "<Attribute>:" + _name;
                        TreeNode _attvalue = new TreeNode();
                        _attvalue.Name = _name;
                        _attvalue.Text = _value;
                        _attvalue.ForeColor = Color.Purple;
                        tnode.Nodes.Add(_attvalue);
                        aux.Nodes.Add(tnode);
                    }
                }   
            }
        }

    }