Question

I have a Windows Forms TreeView that needs to be saved as a xml file.

The structure of the TreeView is like this:

 - Parent
  - Child 1 (Any value)
  - Child 2
    - Child 1 (Any value for a child)

Every TreeNode that has children needs to be saved as a element, and every TreeNode that does not have children needs to be saved as a attribute to it's parent TreeNode

This means the above would result in the following xml:

<?xml version="1.0" encoding="utf-8"?>
<Parent Child1="Any value">
  <Child2 Child1="Any value for a child" />
</Parent>

I tried using the following code, but it did not work when the TreeNodes with no children where below the TreeNodes with children and I couldn't really figure out a good way of doing it.

    public void SerializeTreeView(TreeView treeView, string fileName)
    {
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Indent = true;

        XmlWriter textWriter = XmlWriter.Create(fileName, settings);

        // Writing the xml declaration tag
        textWriter.WriteStartDocument();

        // Save the nodes, recursive method
        SaveNodes(treeView.Nodes, textWriter);

        // End the xml document
        textWriter.WriteEndDocument();
        textWriter.Close();
    }

    private void SaveNodes(TreeNodeCollection nodesCollection, XmlWriter textWriter)
    {
        for (int i = 0; i < nodesCollection.Count; i++)
        {
            TreeNode node = nodesCollection[i];

            if (node.Nodes.Count > 0)
            {
                textWriter.WriteStartElement(node.Name);
            }
            else
            {
                textWriter.WriteAttributeString(node.Name, "Attribute value");
            }

            if (node.Nodes.Count > 0)
                SaveNodes(node.Nodes, textWriter);

            if (node.Nodes.Count > 0)
                textWriter.WriteEndElement();
        }
    }

EDIT:

The problem with the current code is that if I add a TreeNode that has any children and is ABOVE a TreeNode with no children, it gives me the following error:

Token StartAttribute in state Element Content would result in an invalid XML document.

This happens at:

textWriter.WriteAttributeString(node.Name, "Attribute value");

I solved it by sorting the TreeView by child node count (Meaning that the TreeNode with NO children will ALWAYS be below a TreeNode without children)

The solution works, but I would like to figure out why the error occurred and how to fix it.

Était-ce utile?

La solution

How are you filling the TreeView? Are you actually giving the object keys or just titles? Try replacing the two occurences of "node.Name" with "node.Text" (and, for reasons of code sanity, refactoring the multiple checks for Count > 0):

EDIT: ok, try this:

    private void SaveNodes(TreeNodeCollection nodesCollection, XmlWriter textWriter)
    {
        foreach (var node in nodesCollection.OfType<TreeNode>().Where(x => x.Nodes.Count == 0))
            textWriter.WriteAttributeString(node.Name, "Attribute value");

        foreach (var node in nodesCollection.OfType<TreeNode>().Where(x => x.Nodes.Count > 0))
        {
            textWriter.WriteStartElement(node.Name);
            SaveNodes(node.Nodes, textWriter);
            textWriter.WriteEndElement();
        }
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top