Many .NET functions use XmlWriter to output/generate xml. Outputting to a file/string/memory is a very operation:
XmlWriter xw = XmlWriter.Create(PutYourStreamFileWriterEtcHere);
xw.WriteStartElement("root");
...
Sometimes , you need to manipulate the resulting Xml and would therefore like to load it into a XmlDocument or might need an XmlDocument for some other reason but you must generate the XML using an XmlWriter. For example, if you call a function in a 3rd party library that outputs to a XmlWriter only.
One of the things you can do is write the xml to a string and then load it into your XmlDocument:
StringWriter S = new StringWriter();
XmlWriter xw = XmlWriter.Create(S);
/* write away */
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(S.ToString());
However this is inefficient - first you serialize all the xml info into a string, then you parse the string again to create the DOM.
How can you point an XmlWriter to build a XmlDocument directly?
Here's at least one solution:
XmlDocument doc = new XmlDocument();
using (XmlWriter writer = doc.CreateNavigator().AppendChild())
{
// Do this directly
writer.WriteStartDocument();
writer.WriteStartElement("root");
writer.WriteElementString("foo", "bar");
writer.WriteEndElement();
writer.WriteEndDocument();
// or anything else you want to with writer, like calling functions etc.
}
Apparently XpathNavigator gives you a XmlWriter when you call AppendChild()
Credits go to Martin Honnen on : http://groups.google.com/group/microsoft.public.dotnet.xml/browse_thread/thread/24e4c8d249ad8299?pli=1
You could do the opposite : build the XmlDocument
first using DOM, then write it to a XmlWriter
:
XmlDocument xdoc = new XmlDocument();
... // build the document
StringWriter S = new StringWriter();
XmlWriter xw = XmlWriter.Create(S);
xdoc.WriteTo(xw);
You can write xml file using XMLWriter class.
Here is example for this.
XmlWriterSettings objSetting = new XmlWriterSettings();
objSetting.Indent = true;
objSetting.NewLineOnAttributes = true;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
using (XmlWriter objWriter = XmlWriter.Create(sb, objSetting))
{
//Note the artificial, but useful, indenting
objWriter.WriteStartDocument();
objWriter.WriteStartElement("books");
////////Start Book Element///////
objWriter.WriteStartElement("book");
objWriter.WriteStartAttribute("ISBN");
objWriter.WriteValue("asp1");
objWriter.WriteEndAttribute();
objWriter.WriteStartElement("Title");
objWriter.WriteValue("ASP.NET");
objWriter.WriteEndElement();
objWriter.WriteElementString("ReleaseDate", "11/11/2010");
objWriter.WriteStartElement("Pages");
objWriter.WriteValue(200);
objWriter.WriteEndElement(); //price
objWriter.WriteEndElement(); //book
////////End Book Element///////
////////Another Element
////////Start Book Element///////
objWriter.WriteStartElement("book");
objWriter.WriteStartAttribute("ISBN");
objWriter.WriteValue("c#2");
objWriter.WriteEndAttribute();
objWriter.WriteStartElement("Title");
objWriter.WriteValue("C#.NET");
objWriter.WriteEndElement();
objWriter.WriteElementString("ReleaseDate", "10/11/2010");
objWriter.WriteStartElement("Pages");
objWriter.WriteValue(500);
objWriter.WriteEndElement();
objWriter.WriteEndElement(); //book
////////End Book Element///////
objWriter.WriteEndElement(); //books
objWriter.WriteEndDocument();
}
File.WriteAllText(Server.MapPath("BooksList.xml"), sb.ToString());
The idea behind XmlWriter is to wait until you have finished modifying your data before you start writing.
XmlWriter wasn't built with your situation in mind.
Either
- Wait until you know what your data is
going to be before writing
or
- Do what you're currently doing
There is an underlying Stream object that the XmlWriter was writing to, if it was bidirectional (MemoryStream), you could simply re-position it back to -0- and then use the Stream object in the XmlDocument.Load(stream).
HTH,
Z