xmltree

XML's structure is hierarchical and therefore can be displayed in a TreeView control easily. The XMLTree program displays the elements of the XML file in a TreeView control and the attributes of the selected element in a ListView control.

Wikipedia's definition of the Extensible Markup Language or XML is a general-purpose specification for creating custom markup languages. It is classified as an extensible language, because it allows the user to define the mark-up elements. XML's purpose is to aid information systems in sharing structured data, especially via the Internet, to encode documents, and to serialize data.

Now to the code. The load button's click event loads the XML file selected by the user in a System.Xml.XmlDocument object and loops through the root elements. In each iteration a TreeNode object is created and populated using the three functions XmlNode2TreeNode, GetAttributes and FormatName, then added to the TreeView. The XmlNode2TreeNode function is recursive, it calls itself for each child node in the XmlNode passed to it, doing the same thing the loadButton_Click event does for the root elements.

private void loadButton_Click(object sender, EventArgs e)
{
    if (openFileDialog.ShowDialog(this) == DialogResult.Cancel)
        return;
                
    fileNameTextBox.Text = openFileDialog.FileName;
    xmlTreeView.Nodes.Clear();

    document = new XmlDocument();
    document.Load(openFileDialog.FileName);   //load the XMl file

    //loop through the top nodes
    foreach (XmlNode node in document)
    {
        TreeNode treeNode = XmlNode2TreeNode(node);
        GetAttributes(node, treeNode);
        treeNode.Text = FormatName(node);
        xmlTreeView.Nodes.Add(treeNode);
    }
    
    xmlTreeView.ExpandAll();
}

private TreeNode XmlNode2TreeNode(XmlNode parentNode)
{
    TreeNode treeNode = new TreeNode();

    foreach (XmlNode childNode in parentNode.ChildNodes)
    {
        if (childNode.NodeType == XmlNodeType.Element)
        {
            TreeNode childTreeNode = new TreeNode();

            if (childNode.ChildNodes.Count > 0)
                childTreeNode = XmlNode2TreeNode(childNode);

            childTreeNode.Text = FormatName(childNode);
            GetAttributes(childNode, childTreeNode);
            treeNode.Nodes.Add(childTreeNode);
        }
    }

    return treeNode;
}

The FormatName function returns a string formatted according to the XML standards. If the XmlNode contains text data the string returned will be <ElementName>Data</ElementName>. And if the element does not contain data the value returned will be <ElementName>. The GetAttributes function loops through the Attributes collection of the XmlNode passed to it adding them to an array of ListViewItems. The Tag property of the TreeNode object passed in the second parameter is assigned the array. This way the array can be inserted into the ListView on the right side of the form by just casting the Tag property.

private string FormatName(XmlNode node)
{
    string fullName = "<" + node.Name;

    if (node.InnerText != "")
        fullName += ">" + node.InnerText + "</" + node.Name + ">";
    else
        fullName += ">";

    return fullName;
}

private void GetAttributes(XmlNode node, TreeNode treeNode)
{
    if (node.Attributes != null)
    {
        ListViewItem[] attributes = new ListViewItem[node.Attributes.Count];

        for (int i = 0; i < node.Attributes.Count; i++)
        {
            attributes[i] = new ListViewItem(new string[] { 
                node.Attributes[i].Name, node.Attributes[i].Value });
        }

        treeNode.Tag = attributes;
    }
}

private void xmlTreeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    attributesListView.Items.Clear();

    if (e.Node.Tag != null)
    {
        attributesListView.Items.AddRange((ListViewItem[])e.Node.Tag);
    }
}

For more details about XML: