Search code examples
c#xmldeserializationxmlserializermusicxml

How do I differentiate types of XML files before deserializing?


I am loading MusicXML-files into my program. The problem: There are two “dialects”, timewise and partwise, which have different root-nodes (and a different structure):

<?xml version="1.0" encoding='UTF-8' standalone='no' ?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 2.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise version="2.0">
    <work>...</work>
    ...
</score-partwise>

and

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE score-timewise PUBLIC "-//Recordare//DTD MusicXML 2.0 Timewise//EN" "http://www.musicxml.org/dtds/timewise.dtd">
<score-timewise version="2.0">
   <work>...</work>
   ...
</score-timewise>

My code for deserializing the partwise score so far is:

using (var fileStream = new FileStream(openFileDialog.FileName, FileMode.Open))
{
    var xmlSerializer = new XmlSerializer(typeof(ScorePartwise));
    var result = (ScorePartwise)xmlSerializer.Deserialize(fileStream);
}

What would be the best way to differentiate between the two dialects?


Solution

  • 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());