How do I differentiate types of XML files before deserializing?
Here's a way to do it by using an XDocument
to parse the file, read the root element to determine the type, and read it into your serializer.
var xdoc = XDocument.Load(filePath);Type type;if (xdoc.Root.Name.LocalName == "score-partwise") type = typeof(ScorePartwise);else if (xdoc.Root.Name.LocalName == "score-timewise") type = typeof(ScoreTimewise);else throw new Exception();var xmlSerializer = new XmlSerializer(type);var result = xmlSerializer.Deserialize(xdoc.CreateReader());
I would create both serializers
var partwiseSerializer = new XmlSerializer(typeof(ScorePartwise));var timewiseSerializer = new XmlSerializer(typeof(ScoreTimewise));
Assuming that there is only these two I would call CanDeserialize method on one
using (var fileStream = new FileStream(openFileDialog.FileName, FileMode.Open)){ using (var xmlReader = XmlReader.Create(filStream)) { if (partwiseSerializer.CanDeserialize(xmlReader)) { var result = partwiseSerializer.Deserialize(xmlReader); } else { var result = timewiseSerializer.Deserialize(xmlReader); } }}
Obviously this is just an idea how to do it. If there were more options or according to your application design I would use a more sophisticated way to call CanDeserialize, but that method is the key in my opinion:
http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.candeserialize.aspx
The XmlReader class can be found here:
http://msdn.microsoft.com/en-us/library/System.Xml.XmlReader(v=vs.110).aspx
If you're concerned about resource usage:
internal const string NodeStart = "<Error "; public static bool IsErrorDocument(string xml) { int headerLen = 1; if (xml.StartsWith(Constants.XMLHEADER_UTF8)) { headerLen += Constants.XMLHEADER_UTF8.Length; } else if (xml.StartsWith(Constants.XMLHEADER_UTF16)) { headerLen += Constants.XMLHEADER_UTF16.Length; } else { return false; } if (xml.Length < headerLen + NodeStart.Length) { return false; } return xml.Substring(headerLen, NodeStart.Length) == NodeStart; }internal class Constants{ public const string XMLHEADER_UTF16 = "<?xml version=\"1.0\" encoding=\"utf-16\"?>"; public const string XMLHEADER_UTF8 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";}