I’m not a huge fan of the XmlWriter API. In particular, remembering to close every tag.
It would be nice to have something like Haml, where the nesting takes care of it. A bit tricky in C#, but you can get some of the effect by (ab)using IDisposable:
public class SelfClosingXmlWriter { private readonly XmlWriter _xmlWriter; public SelfClosingXmlWriter(XmlWriter xmlWriter) { _xmlWriter = xmlWriter; } public XmlElementCookie WriteStartElement(string localName) { _xmlWriter.WriteStartElement(localName); return new XmlElementCookie(_xmlWriter); } public XmlAttributeCookie WriteStartAttribute(string localName) { _xmlWriter.WriteStartAttribute(localName); return new XmlAttributeCookie(_xmlWriter); } public void WriteRaw(string xml) { _xmlWriter.WriteRaw(xml); } public void WriteString(string xml) { _xmlWriter.WriteString(xml); } public void WriteAttributeString(string localName, string value) { _xmlWriter.WriteAttributeString(localName, value); } public class XmlElementCookie : IDisposable { private readonly XmlWriter _xmlWriter; public XmlElementCookie(XmlWriter xmlWriter) { _xmlWriter = xmlWriter; } public void Dispose() { _xmlWriter.WriteEndElement(); } } public class XmlAttributeCookie : IDisposable { private readonly XmlWriter _xmlWriter; public XmlAttributeCookie(XmlWriter xmlWriter) { _xmlWriter = xmlWriter; } public void Dispose() { _xmlWriter.WriteEndAttribute(); } } }
Which lets you go from this:
var writer = XmlWriter.Create("out.xml", settings); writer.WriteStartElement("book"); writer.WriteStartElement("author"); writer.WriteStartElement("name"); writer.WriteString("Big John"); writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteStartElement("title"); writer.WriteString("Amazing Cakes!"); writer.WriteEndElement(); writer.WriteEndElement();
To this:
var writer = new SelfClosingXmlWriter(XmlWriter.Create("out.xml", settings)); using (writer.WriteStartElement("book")) { using (writer.WriteStartElement("author")) { using (writer.WriteStartElement("name")) { writer.WriteString("Big John"); } } using (writer.WriteStartElement("title")) { writer.WriteString("Amazing Cakes!"); } }