在C#中处理多版本XML文件的方法

时间:2014-12-23 14:37:16

标签: c# xml wpf serialization xsd

我需要一些帮助来设计适当的解决方案来处理各种版本的XML文件。

编程语言:C#

平台:Windows(WPF)

目前我处理一堆结构相同的XML文件。 XML文件中是架构版本号。为了给您一个想法,请考虑以下示例: (请注意,以下仅为伪数据,可能包含一些拼写错误)

版本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>

为了处理XML数据,我通过Visual Studio XSD工具创建了一个XML模式,并生成了一个看起来像(剥离)的相应类:

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;
    }
 }
} .....

对于数据表示部分,我创建了另一个使用可用数据子集的类:

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

读取XML数据后,处理工作正常如下:

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

基本上处理数据可以看作:

carInfo.Type = smlCarInformationEngine.Type;

Presentation Class的字段是从(XSD)生成的类的字段

中分配的值

到目前为止一切顺利。数据可以成功处理,每个人都很高兴。

但是,一段时间后,XML数据文件发生了变化:

<?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>

这正是问题开始出现的地方。 通常,架构几乎相同 - 但是一些字段可能会被更改,添加,删除,移动。 正如您在上面的示例中所看到的,&#34;传输&#34;被移动了&#34;容量&#34;加入。

以前生成的XSD架构没有反映出这一点,创建一个与旧架构几乎完全相同的新架构,并将其与生成的类一起添加到Visual Studio项目中会导致声明类的含糊不清(这几乎很明显)所有属性都相同)。 删除旧模式及其类并将其替换为新模式会导致错误,例如

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

这很清楚,因为Transmission不再是新模式中Engine类的一部分。

由于我当时可以构建我的应用程序的新版本并包含新类,因此我或多或少可以选择使用哪种方式来处理新的XML模式。 我当时仍然需要的是能够阅读&#34; old&#34; XML数据文件(以及具有新架构的XML文件)。

我可以编写新的方法来处理各种XML版本(将来会对架构进行一些更改),但我不想为每个XML版本重复表示层的代码(因为有几十个)在更改代码时成为行政噩梦的代码行)。 我知道有一些商业工具可以处理XSD架构更改,将它们合并为一个并生成类,但是在这个项目中不能选择在许可证上花钱。

那里有谁可以就处理类似XML文件的可行方法分享一些想法?

非常感谢, 阿尔伯特

1 个答案:

答案 0 :(得分:0)

此类问题的常见解决方案是为每个新版本的XML创建该接口的接口和具体实现。在这种情况下可能更合适的替代方法是使用abstract基类和一些abstract方法以及派生类可以调用的一些受保护方法。在这种情况下,您可以将公共代码放入基类并从派生类中调用它。这是一个简单的例子:

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() 
    }
}