Заполнение дерева просмотра из XML - PullRequest
0 голосов
/ 14 декабря 2011

В настоящее время я пытаюсь заполнить древовидное представление из 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>

Все, что я хочу сделать, это отобразить имя группы, а затем вы сможете развернуть и просмотреть подгруппы. В настоящее время у меня это работает, но все в одном линейном представлении. Вот мой код, который у меня сейчас есть:

  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 ]

2 голосов
/ 14 декабря 2011

Вы можете попробовать использовать это, используя 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 голос
/ 08 мая 2015

Мне нужно что-то подобное. Мне понравилось добавление атрибута в ответе 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 и т. Д. Надеюсь, это кому-нибудь поможет.

0 голосов
/ 24 января 2014

Я воспользовался вашими кодами ответов и обнаружил, что некоторые 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);
                    }
                }   
            }
        }

    }
0 голосов
/ 14 декабря 2011

Вы правильно используете рекурсию для перемещения по XML-файлу, к сожалению, вы добавляете триоды в корень Treeview на каждой итерации. Вместо этого измените ваш код, добавив дочерние узлы к триоду, обрабатываемому в вашем цикле, например,

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);
    }
...