Get Stream from XmlReader

As a result of the stored procedure, I get a SqlXml object from which I can call CreateReader to get the standard XmlReader so that I can process it in my DLL.

At the business level of the application, I have an XMySerializer that can read xml and instantiate a business object.

However, the XMySerializer.Deserialize function accepts System.IO.Stream as an input.

So the question is, how can I get System.IO.Stream from a System.Xml.XmlReader ? The opposite will be easier ...

+6
source share
4 answers

I think there is no way to get the stream used by XmlReader. A workaround would be to use XmlReader.ReadOuterXml() to get all the XML as a string and put it in a MemoryStream .

+3
source

Actually, you can.
It just requires some libraries that not everyone uses because they are part of BizTalk.
If you have access to the BizTalk runtime, you can use XmlTranslatorStream to provide the Stream from the XmlReader example:

 var xmlStream = new XmlTranslatorStream(xmlReader); 

There are 3 constructors you can use.

Yes, there are very heavy requirements for getting a stream from XmlReader, so you can understand why most of the answers are equal to "you cannot get from here!"

Hope that helps
Jay

+8
source

XmlReader may or may not be supported by Stream . I tricked myself with some methods, using reflection to try to get a Stream or TextWriter , supporting XmlReader, but in the end, I think that it is probably easiest to write an object to a new stream; I would recommend this method for the accepted answer, because the accepted answer will not work very well on large documents, and this is basically a simplified version of what the BizTalk version in Jay answer will do (BizTalk does some automatic detection of whether it should use FileStream or MemoryStream and has other special processing for XML):

 public static class XmlExtensions { public static MemoryStream ToStream(this XmlReader reader) { MemoryStream ms = new MemoryStream(); reader.CopyTo(ms); return ms; } public static FileStream ToStream(this XmlReader reader, string fileName) { FileStream fs = new FileStream(fileName, FileMode.Create); reader.CopyTo(fs); return fs; } public static void CopyTo(this XmlReader reader, Stream s) { XmlWriterSettings settings = new XmlWriterSettings(); settings.CheckCharacters = false; // don't get hung up on technically invalid XML characters settings.CloseOutput = false; // leave the stream open using (XmlWriter writer = XmlWriter.Create(s, settings)) { writer.WriteNode(reader, true); } } } 

CopyTo allows you to customize the stream as you like; ToStream gives you some useful common cases when you just want to quickly get a regular MemoryStream (for small XML files) or use FileStream (for larger ones).

Of course, in the end, if you really do this for serialization purposes, it would be nice to add overloading to your serialization class, for example:

 XMySerializer.Deserialize(XmlReader reader, object graph) 

Both XmlSerializer and DataContractSerializer in BCL follow this idea ...

+3
source

You can not. XmlReader is an abstract class that has many implementations (including some that are read from threads, while others have nothing to do with threads). However, you can write data in this XML reader to System.IO.MemoryStream , and then pass this stream to your XMySerializer.Deserialize function.

+1
source

Source: https://habr.com/ru/post/892036/


All Articles