XmlDocument.Load using MemoryStream...

G

Guest

Hello. Not very experienced using Streams of any kind, and Google didn't
save me...

I have some code that builds an Xml file and dumps it on my drive. It
works. Now, I want to do the same thing, but skip the file and just hold the
XmlDocument in memory and pass it around to various methods. Essentially, my
code is this:

-----------------------------

XmlDocument myXmlDocument = new XmlDocument();
MemoryStream myStream = new MemoryStream();
XmlTextWriter myWriter = new XmlTextWriter(myStream, Encoding.UTF8);

// Code to build the XmlDocument using myWriter
myWriter.WriteStartDocument();
myWriter.WriteStartElement(...

// continue building the XmlDocument using myWriter

myWriter.WriteEndDocument();
myXmlDocument.Load(myStream);
myWriter.Flush();
myWriter.Close();

return myXmlDocument;

---------------------

The exception occurs on the "myXmlDocument.Load(myStream)
line...System.Xml.XmlException: The root element is missing...

Anyone help me out? Thanks in advance.
 
C

C.C. \(aka Me\)

You will need to change the read/write position of the Stream. As you write
data to a Stream the current location pointer moves. This pointer is used
for both read and write operations so when you try to perform the Load() it
reads in nothing (because the read location is at the end of the Stream from
the last write command.)

To change the current read/write location you can do the following right
before the xmlDocument.Load() call:

myStream.Seek(0, System.IO.SeekOrigin.Begin);

This will move the read/write location back to the start of the Stream and
allow the XMLDocument to read in the entire contents. Keep in mind however
that if you want to write more data to the Stream you will need to move the
read/write pointer back to the end of the stream with the same command (just
different parameters.)

Hope this helps!
 
G

Guest

Sorry, no go. Same error. I've noticed that the Length and Position of
myStream are always 0. I am forced to conclude that the myXmlTextWriter is
not writing to the MemoryStream. Unfortunately, I have no clue why not, and
I find that the documentation around this topic is of little help to me....

Any help appreciated. Thanks in advance. I rather obviously am clueless
about how to use Streams.... :(
 
C

C.C. \(aka Me\)

Here is the code that I am using. I have a simple form with a button and a
text box on it. When I click the button I exectute this code which populates
the text box.

++++++++++++++++++++++++++++++++++++++++++++++++++++++
System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
System.IO.MemoryStream myStream = new System.IO.MemoryStream();
System.Xml.XmlTextWriter myWriter = new System.Xml.XmlTextWriter(myStream,
System.Text.Encoding.ASCII);
// Code to build the XmlDocument using myWriter
myWriter.WriteStartElement("RootNode");
myWriter.WriteStartElement("Node1");
myWriter.WriteString("Node1 Data");
myWriter.WriteEndElement();
myWriter.WriteStartElement("Node2");
myWriter.WriteString("Node2 Data");
myWriter.WriteEndElement();
myWriter.WriteEndElement();
myWriter.Flush();
myStream.Seek(0, System.IO.SeekOrigin.Begin);
xmlDoc.Load(myStream);
myWriter.Close();
txtXML.Text = xmlDoc.InnerXml;
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=

Maybe give it a try and see what happens? It works fine on my system so it
should on yours too.
 
G

Guest

Hey,

Thanks, it worked. The problem was the myWriter.Flush() method. I had it
in the wrong place!! I didn't fully understand what it did, I thought it was
part of clean up. Needed to do that before the myStream.Seek() and
myXmlDocument.Load() method calls. Silly me.

While I have you though, could you tell me using the
MemoryStream/XmlTextWriter combo to make my XmlDocument is preferable to just
building the XmlDocument directly? Or is this just a "more than one way to
skin a cat" kinda deal.

Thanks again!
 
J

Jon Skeet [C# MVP]

memyselfandI said:
Thanks, it worked. The problem was the myWriter.Flush() method. I had it
in the wrong place!! I didn't fully understand what it did, I thought it was
part of clean up. Needed to do that before the myStream.Seek() and
myXmlDocument.Load() method calls. Silly me.

While I have you though, could you tell me using the
MemoryStream/XmlTextWriter combo to make my XmlDocument is preferable to just
building the XmlDocument directly? Or is this just a "more than one way to
skin a cat" kinda deal.

It's not, particularly - unless you're passing the "new" document to a
method which might modify it, and you want to keep hold of the
original.

Even if you *do* want to clone, you should look at calling
XmlDocument.CloneNode instead, as it's a lot easier than writing it all
out and reading it back in.
 
C

C.C. \(aka Me\)

There are a ton of ways to create XML and it probably just depends on how
much you want to hand code in terms of the XML.

You could just do something like this if you wanted:

String xml = "";
XmlDocument xmlDoc = new XmlDocument();
xml = "<RootNode>\r\n";
xml += "<Node1>Node1 value</Node1>\r\n";
xml += "</RootNode>\r\n";
xmlDoc.LoadXml(xml); //Might not be the correct method - I am just typing
this from memory.

This will create the xml as a string and them shove it into the XmlDocument.
If you only have a few items to add then this may be the way to go? Or you
could create a method that takes a node name (RootNode, None1, etc.) and a
value (Node1 Value) as parameters and it does the above for you.

It just depends on what you need to do and how much XML specific stuff you
want to deal with.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top