简体   繁体   中英

Approach to process multi version XML files in C#

I'd need some assistance with designing a proper solution for processing various versions of XML files.

Programming Language: C#

Platform: Windows (WPF)

Currently I process a bunch of XML files with the same structure. Within the XML files is a schema version number. To give you an idea, consider the following example: (Please be aware that following is pseudo data only and might contain some typos)

Version 1:

<?xml version="1.0" encoding="utf-8"?>
 <sml Version="1.0.5" ....>
  <Car>
   <Information>
    <Engine>
     <Type>Diesel</Type>
     <Transmission>5-speed</Transmission>
    </Engine>
    <Color>blue</Color> 
   </Information>
  </Car>
</sml>

To process the XML data, I created a XML schema via the Visual Studio XSD tool and generated a corresponding class which looks like (stripped):

public partial class sml {
 private smlCarInformation[][] carField;
 private string versionField;
 public smlCarInformation[][] Car {
    get {
        return this.carField;
    }
    set {
        this.carField = value;
    }
 }

 public string Version {
    get {
        return this.versionField;
    }
    set {
        this.versionField = value;
    }
 }
}
public partial class smlCarInformationEngine {    
 private string typeField;
 private string transmissionField;
 public string Type {
    get {
        return this.typeField;
    }
    set {
        this.typeField = value;
    }
 }

 public string Transmission {
    get {
        return this.transmissionField;
    }
    set {
        this.transmissionField = value;
    }
 }
} .....

For the data presentation part, I created another class that uses a subset of the available data:

public class DisplayCarInformation {
 public string Model;
 public string Type;
 public int HorsePower;
 public string Transmission;
}

After reading XML data, processing works fine like:

DisplayCarInformation carInfo=new DisplayCarInformation();
carInfo.Model="Ford";
carInfo.Type=smlCarInformationEngine.Type;
carInfo.Transmission=smlCarInformationEngine.Transmission;

Basically processing data can be seen as:

carInfo.Type=smlCarInformationEngine.Type;

Fields of Presentation Class are assigned values from fields of the (XSD) generated class

So far so good. Data can be processed successfully and everybody is happy.

However, some time later, XML data files are changed:

<?xml version="1.0" encoding="utf-8"?>
 <sml Version="1.0.6" ....>
  <Car>
   <Information>
    <Engine>
     <Type>Diesel</Type> 
     <Capacity>1980</Capacity>        
    </Engine>
    <Color>blue</Color> 
    <Transmission>5-speed</Transmission>
   </Information>
  </Car>
</sml>

And that's exactly where problems start to pop up. Generally, the schema is almost identical - however a few fields might get changed, added, deleted, moved. As you can see in above sample, "Transmission" was moved and "Capacity" added.

The previous generated XSD schema does not reflect that, creating a new schema that is almost identical as the old one and adding it with its generated class to the Visual Studio project results in an ambiguity of declared classes (which is clear as almost all properties are identical). Removing the old schema and it's class and replacing it with the new schema, results in an error at eg

carInfo.Transmission=smlCarInformationEngine.Transmission; results in an error 

which is clear, as Transmission is not part anymore of the class Engine in the new schema.

As I can build a new version of my application at that time and include new classes, I am more or less free to opt which way to go to handle the new XML schema. What I still need at that time is to be able to read "old" XML data files (as well as XML files with the new schema).

I could write new methods to handle various XML versions (and there will be several changes to the schema in the future), but I do not want to repeat code for the presentation layer for each XML version (as there are several dozens lines of codes which becomes an administrative nightmare when changing code). I know that there are commercial tools available that could handle XSD schema changes, combine them into one and generate classes, but spending money on licences is not an option in this project.

Anybody out there who could share some ideas on a viable approach to process similar XML files?

Thank you very much, Albert

A common solution to this kind of problem is to create an interface and a concrete implementation of that interface for each new version of XML. An alternative that might be more appropriate in this exact situation would be to use an abstract base class with some abstract methods and some protected methods that derived classes can call. In this case, you could put your common code into the base class and call it from the derived classes. Here's a simple example:

public abstract class BaseConversion
{
    public abstract string VersionNumber { get; set; }

    public abstract string MethodToBeImplementedInEachDerivedClass();

    protected void MethodImplementedHereToBeUsedByDerivedClasses() 
    {
        // Implement common code here
    }
}

public class Schema147Conversion : BaseConversion
{
    public override string VersionNumber { get { return "147"; } }

    public override string MethodToBeImplementedInEachDerivedClass()
    {
        return ""; // Implement schema specific code here... 
        // can use MethodImplementedHereToBeUsedByDerivedClasses() 
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM