Reputation: 2385
My code crashes when using the XmlWriter, saying it is used by another process.
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.
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? 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();
}
}
}
Upvotes: 0
Views: 990
Reputation: 19407
The file when accessed by the XmlWriter will become locked, so an subsequent attempts to read it result in error.
You can change the function to pass the writer as a parameter, thereby have one copy and hopefully avoid the issue.
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
Upvotes: 3
Reputation: 875
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();
}
}
Upvotes: 0
Reputation: 31184
that's because you're opening multiple instances of your XmlWriter writer
at once.
What you should do, is put your using
statement outside the recursive function, and then pass your XmlWriter
in
using (XmlWriter writer = XmlWriter.Create("C:\\ui.xml"))
{
generateXml(c, writer);
Upvotes: 0