Friday, August 20, 2010

Extending XDocument class to provide ToXml() and ToStream()

I recently encountered some particularities of the .Net framework when it comes to XDocument class.
  •  First, the ToString() method, gives you the Xml contained in the docuemnt as a string indeed, but it completely forgets the Xml declaration.
  • Second, the Save method when called on an XmlWriter has a strange behavior.
Here are two extension methods to nicely deal with this issue.

public static class ConversionExtensions {

        public static string ToXml(this XDocument document) {
            if(document.Declaration == null) {
                document.Declaration = new XDeclaration("1.0", "utf-8", "no");
            }

            var sb = new StringBuilder();
            using(var writer = XmlWriter.Create(sb)) {
                document.Save(writer);
            }
            return sb.ToString();
        }

        public static Stream ToStream(this XDocument document) {
            var stream = new MemoryStream();
            using(var writer = XmlWriter.Create(stream, new XmlWriterSettings
            {
                Indent = true
            })) {
                document.Save(writer);
            }
            stream.Position = 0;
            return stream;
        }
    }
Notice how I use the Save() method instead of ToString() on the first extension so the Xml declaration is not omitted.

The important thing in the second extension is to reset the position of the stream to 0, otherwise the consumer of the stream will not see any data in there.

The other important think in both methods, it so wrap the XmlWriter into a using block. Unless you do that, you might end up with no data at all in your return value, since the XmlWriter is buffered. You can alternatively call the Close() method on the writer explicitely.

No comments:

Post a Comment