使用属性和元素将TreeView另存为xml

时间:2013-05-15 12:41:19

标签: c# xml winforms recursion treenode

我有一个需要保存为xml文件的Windows窗体TreeView。

TreeView的结构如下:

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

每个有子节点的TreeNode都需要保存为元素,每个没有子节点的TreeNode都需要作为属性保存到它的父TreeNode

这意味着上面会产生以下xml:

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

我尝试使用下面的代码,但是当没有子节点的TreeNodes在带有子节点的TreeNodes下面时,它无法正常工作。

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

编辑:

当前代码的问题是,如果我添加一个有任何子节点并且上面没有子节点的TreeNode,它会给我以下错误:

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

这发生在:

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

我通过子节点计数对TreeView进行排序来解决它(意味着没有子节点的TreeNode总是低于没有子节点的TreeNode)

解决方案有效,但我想弄清楚错误发生的原因以及解决方法。

1 个答案:

答案 0 :(得分:3)

你是如何填充TreeView的?你实际上是给对象键还是标题?尝试用“node.Text”替换“node.Name”的两个出现(并且出于代码健全的原因,重构Count&gt; 0的多个检查):

编辑:好的,试试这个:

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