简体   繁体   English

如何递归使用XmlWriter?

[英]How to use XmlWriter recursively?

My code crashes when using the XmlWriter, saying it is used by another process. 使用XmlWriter时,我的代码崩溃了,并说它被另一个进程使用。

    private void generateXml(Control receivedControl)
    {
        foreach (Control subCtrl in receivedControl.Controls)
        {
            using (XmlWriter writer = XmlWriter.Create("C:\\ui.xml"))
            {
                writer.WriteStartElement(subCtrl.Name);
                generateXml(subCtrl);
                writer.WriteEndElement();
            }
        }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        foreach (Control c in this.Controls)
        {
            generateXml(c);
        }
    }

Here's the error I get debugging: 这是我得到调试的错误:

Additional information: The process cannot access the file 'C:\\ui.xml' because it is being used by another process. 附加信息:该进程无法访问文件'C:\\ ui.xml',因为它正在被另一个进程使用。

EDIT: So thanks to you I've managed to get the recursion working, but it only writes the last object in the xml file, anybody knows why? 编辑:因此,感谢您,我已经设法使递归起作用,但是它仅将最后一个对象写入xml文件中,有人知道为什么吗? Here's the updated code: 这是更新的代码:

    private void generateXml(XmlWriter receivedWriter, Control receivedControl)
    {
        receivedWriter.WriteStartElement(receivedControl.Name);
        foreach (Control subCtrl in receivedControl.Controls)
        {
            generateXml(receivedWriter, subCtrl);
        }
        receivedWriter.WriteEndElement();
    }
    private void button2_Click(object sender, EventArgs e)
    {
        foreach (Control c in this.Controls)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;

            using(XmlWriter writer = XmlWriter.Create("c:\\ui.xml", settings))
            {
                writer.WriteStartDocument();
                writer.WriteStartElement("Form");
                generateXml(writer, c);
                writer.WriteEndElement();
                writer.WriteEndDocument();
            }
        }
    }

The file when accessed by the XmlWriter will become locked, so an subsequent attempts to read it result in error. XmlWriter访问该文件时,该文件将被锁定,因此后续尝试读取该文件将导致错误。

You can change the function to pass the writer as a parameter, thereby have one copy and hopefully avoid the issue. 您可以更改函数以将writer作为参数传递,从而获得一个副本,并希望避免该问题。

private void generateXml(XmlWriter writer, Control receivedControl)
{
    foreach (Control subCtrl in receivedControl.Controls)
    {
            writer.WriteStartElement(subCtrl.Name);
            generateXml(writer, subCtrl);
            writer.WriteEndElement();
    }
}

private void button2_Click(object sender, EventArgs e)
{
    using (XmlWriter writer = XmlWriter.Create("C:\\ui.xml"))
    {
        writer.WriteStartDocument();
        writer.WriteStartElement(this.Name); // This is the document element
        foreach (Control c in this.Controls)
        {
            generateXml(writer, c);
        }
        writer.WriteEndDocument(); // Close any open tags
    }
}

Above is a sample - not tested. 以上是示例-未测试。

Edit : Updated to include root element 编辑:更新为包括根元素

that's because you're opening multiple instances of your XmlWriter writer at once. 那是因为您要一次打开XmlWriter writer器的多个实例。

What you should do, is put your using statement outside the recursive function, and then pass your XmlWriter in 您应该做的是将using语句放在递归函数之外,然后将XmlWriter传递给

using (XmlWriter writer = XmlWriter.Create("C:\\ui.xml"))
{
    generateXml(c, writer);

you can also use a File that shares write access 您还可以使用共享写访问权限的文件

        using (var f = new FileStream("C:\\ui.xml",      FileMode.Append,FileAccess.Write,FileShare.Write))
            {
                using (XmlWriter writer = XmlWriter.Create(f))                 
                {
                    writer.WriteStartElement(subCtrl.Name);
                    generateXml(subCtrl);
                    writer.WriteEndElement();
                }
            }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM