如何使用C#将XML文件/字符串渲染到Winforms中的TreeView组件中

本文概述

是否在寻找一种将整个XML文档呈现到Winforms的可扩展TreeView中的方法?你当然不希望遍历每个节点, 并根据节点包含的类型和数据写很多” if”, 不是吗?相反, 我们希望与你分享一种有趣的方法, 该方法如何将任何XML文件结构自动呈现到Winforms的TreeView组件中, 这将使你的生活更轻松。

在本文中, 我们将向你展示如何使用C#将整个XML文档呈现到Winforms应用程序的TreeView中。

1.了解渲染逻辑

在此示例中, 我们将有一个treeView1变量, 该变量代表通过工具箱中的拖放添加到表单的TreeView组件。第一步, 你需要创建一个包含XML字符串的变量, 可以从本地或远程源获取该变量, 因此, 基本上由你决定如何从要呈现的XML文件中检索数据。接下来, 使用创建的实例中的LoadXml方法使用你拥有的字符串XML数据创建XmlDocument的新结构。

因为我们假设你可能已经在treeView中包含了一些数据, 所以我们将使用TreeView的Nodes.Clear方法清除渲染过程之前的所有节点。现在, 你知道, 在每个XML文件上都有一个文档名称, 用于定义文件的含义, 例如:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
	<url>
		<loc>https://www.sitemaps.org/</loc>
		<lastmod>2016-11-21</lastmod>
	</url>
</urlset>

在先前的XML文件上, 文档名称为urlset, 以此类推。按照我们的逻辑, 我们还将添加此节点, 并且它将基本上包含文件的所有节点。这必须手动完成, 因此使用Node.Add将节点添加到treeView中, 然后将该节点存储到变量中, 该变量将作为辅助方法AddNode的参数提供:

try
{
    // 1. Read XML File from a local path
    string xmlString = File.ReadAllText(@"C:\Users\sdkca\Desktop\myXMLFile.xml", Encoding.UTF8);

    // 2. Create a XML DOM Document and load the data into it.
    XmlDocument dom = new XmlDocument();
    dom.LoadXml(xmlString);

    // 3. Initialize the TreeView control. treeView1 can be created dinamically
    // and attached to the form or you can just drag and drop the widget from the toolbox
    // into the Form.

    // Clear any previous content of the widget
    treeView1.Nodes.Clear();
    // Create the root tree node, on any XML file the container (first root)
    // will be the DocumentElement name as any content must be wrapped in some node first.
    treeView1.Nodes.Add(new TreeNode(dom.DocumentElement.Name));

    // 4. Create an instance of the first node in the treeview (the one that contains the DocumentElement name)
    TreeNode tNode = new TreeNode();
    tNode = treeView1.Nodes[0];

    // 5. Populate the TreeView with the DOM nodes with the helper 'AddNode' function
    this.AddNode(dom.DocumentElement, tNode);
}
catch (XmlException xmlEx)
{
    MessageBox.Show(xmlEx.Message);
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

辅助方法AddNode如下:

/// <summary>
/// Renders a node of XML into a TreeNode. Recursive if inside the node there are more child nodes.
/// </summary>
/// <param name="inXmlNode"></param>
/// <param name="inTreeNode"></param>
private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
{
    XmlNode xNode;
    TreeNode tNode;
    XmlNodeList nodeList;

    // Loop through the XML nodes until the leaf is reached.
    // Add the nodes to the TreeView during the looping process.
    // If the node has child nodes, the function will call itself.
    if (inXmlNode.HasChildNodes)
    {
        nodeList = inXmlNode.ChildNodes;

        for (int i = 0; i <= nodeList.Count - 1; i++)
        {
            xNode = inXmlNode.ChildNodes[i];
            inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
            tNode = inTreeNode.Nodes[i];
            AddNode(xNode, tNode);
        }
    }
    else
    {
        // Here you need to pull the data from the XmlNode based on the
        // type of node, whether attribute values are required, and so forth.
        inTreeNode.Text = (inXmlNode.OuterXml).Trim();
    }
}

基本上, 它将每个XML节点转换为TreeView节点。

2.完整的例子

既然我们已经解释了逻辑, 我们就可以继续执行表单了。在此示例中, 我们将在表单上有2个元素, 一个TreeView即treeView1和一个按钮即button1, 我们从工具箱中拖动它们并将其手动附加到表单上。

然后, 在我们的代码中, 我们将向按钮添加一个事件侦听器, 因此, 当用户单击一个打开的文件对话框时, 将显示一个对话框, 并允许他选择一个将呈现到树视图中的XML文件:

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

namespace Sandbox
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// When the user clicks on the Load XML button, an open File Dialog will
        /// appear, allowing you to pick an XML file to render in the treeview
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog saveFileDialog1 = new OpenFileDialog();
            saveFileDialog1.Filter = "XML Files (*.xml)|*.xml";
            saveFileDialog1.FilterIndex = 2;
            saveFileDialog1.RestoreDirectory = true;

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                this.RenderXMLFile(saveFileDialog1.FileName);
            }
        }

        private void RenderXMLFile(string filepath)
        {
            try
            {
                // 1. Read XML File from a local path
                string xmlString = File.ReadAllText(filepath, Encoding.UTF8);

                // 2. Create a XML DOM Document and load the data into it.
                XmlDocument dom = new XmlDocument();
                dom.LoadXml(xmlString);

                // 3. Initialize the TreeView control. treeView1 can be created dinamically
                // and attached to the form or you can just drag and drop the widget from the toolbox
                // into the Form.

                // Clear any previous content of the widget
                treeView1.Nodes.Clear();
                // Create the root tree node, on any XML file the container (first root)
                // will be the DocumentElement name as any content must be wrapped in some node first.
                treeView1.Nodes.Add(new TreeNode(dom.DocumentElement.Name));

                // 4. Create an instance of the first node in the treeview (the one that contains the DocumentElement name)
                TreeNode tNode = new TreeNode();
                tNode = treeView1.Nodes[0];

                // 5. Populate the TreeView with the DOM nodes.
                this.AddNode(dom.DocumentElement, tNode);
            }
            catch (XmlException xmlEx)
            {
                MessageBox.Show(xmlEx.Message);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// Renders a node of XML into a TreeNode. Recursive if inside the node there are more child nodes.
        /// </summary>
        /// <param name="inXmlNode"></param>
        /// <param name="inTreeNode"></param>
        private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
        {
            XmlNode xNode;
            TreeNode tNode;
            XmlNodeList nodeList;
            int i;

            // Loop through the XML nodes until the leaf is reached.
            // Add the nodes to the TreeView during the looping process.
            if (inXmlNode.HasChildNodes)
            {
                nodeList = inXmlNode.ChildNodes;

                for (i = 0; i <= nodeList.Count - 1; i++)
                {
                    xNode = inXmlNode.ChildNodes[i];
                    inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
                    tNode = inTreeNode.Nodes[i];
                    this.AddNode(xNode, tNode);
                }
            }
            else
            {
                // Here you need to pull the data from the XmlNode based on the
                // type of node, whether attribute values are required, and so forth.
                inTreeNode.Text = (inXmlNode.OuterXml).Trim();
            }
        }
    } 
}

如本文开头所述, 此方法适用于XML的每种结构, 只需加载一个随机文件, 它就会在Tree View中呈现。这种方法是通用的, 但可以轻松自定义, 因此你可以随意修改以添加条件以按数据和其他内容进行过滤。

编码愉快!

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?