Clean-up job in a recent project that uses XML to store certain data. What I found:![]()
- an XSD describing the XML schema
- C# proxy classes previously generated by the VS xsd.exe tool
- the actual XML files
- all of them not always in sync
The code reading and writing the XML files used LinqToXml to query the files and manually instantiate the XSD-generated classes.
Since the purpose of the proxy classes is to simplify read, write and query operations on statically typed classes, I replaced the Xml.Linq with compile-time type-safe object operations.
In order to verify that my changes did not corrupt the file or change any of the data, I needed to compare the original .xml files and the ones generated by XmlSerializer. I noticed differences between the two sets caused by the classes that wrote the files:
- XDocument.Root.Save does not generate namespace declarations, and writes a <element></element> closing tag for empty data.
- XmlSerializer does not write an explicit closing tag but uses the <element /> notation, and generates some namespace declarations in the <?xml> header.
I found the first hints of dealing with the closing tag here and here by implementing an XmlTextWriter, and the final code looks like this:
class MyXmlTextWriter : XmlTextWriter
{
public MyXmlTextWriter(Stream w)
: base(w, Encoding.UTF8)
{
Indentation = 2;
IndentChar = ' ';
Formatting = System.Xml.Formatting.Indented;
}
public override void WriteEndElement()
{
if (this.WriteState == System.Xml.WriteState.Element)
Formatting = System.Xml.Formatting.None;
base.WriteFullEndElement();
Formatting = System.Xml.Formatting.Indented;
}
}
To omit the namespace declarations, one needs to provide an XmlSerializerNamespaces object for the XmlSerializer:
XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add(string.Empty, string.Empty); ns.Add(string.Empty, "http://www.w3.org/2001/XMLSchema-instance"); ns.Add(string.Empty, "http://www.w3.org/2001/XMLSchema"); using (var fs = new FileStream(filename, FileMode.Create, FileAccess.Write)) serializer.Serialize(new MyXmlTextWriter(fs), app, ns);

[...] I researched the topic of my recent post about the XmlSerializer I became aware that there are more ways to process XML data in .Net than I knew about. Here is an [...]