2014-12-23 27 views
1

我需要一些幫助來設計處理各種版本的XML文件的適當解決方案。在C#中處理多版本XML文件的方法

編程語言:C#

平臺:視窗(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;

演示類的字段是從(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> 

而這正是問題開始流行起來。 通常,模式幾乎是相同的 - 但是可能會更改,添加,刪除和移動一些字段。 正如您在上面的示例中看到的,「傳輸」已被移動並且「容量」被添加。

以前生成的XSD模式沒有反映出來,創建一個與舊模式幾乎完全相同的新模式,並將其與生成的類一起添加到Visual Studio項目中導致聲明類的歧義性(這是明確的幾乎所有的屬性都是相同的)。 刪除舊的模式及其類並將其替換爲新的模式,會導致錯誤。

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

這很清楚,因爲傳輸不再是新模式中類的引擎。

由於當時我可以構建新版本的應用程序幷包含新類,所以我可以自由選擇處理新XML模式的方式。 當時我仍然需要的是能夠讀取「舊」XML數據文件(以及具有新模式的XML文件)。

我可以編寫新的方法來處理各種XML版本(並且將來會對模式進行一些更改),但我不想爲每個XML版本的表示層重複代碼(因爲有幾個幾十行代碼,在更改代碼時會變成行政噩夢)。 我知道有些商業工具可以處理XSD模式更改,將它們合併爲一個並生成類,但是在這個項目中並不是一個選項。

有誰可以分享一些可行的方法來處理類似的XML文件的一些想法?

非常感謝你, 阿爾伯特

+0

你可能需要一個映射層,使舊格式達到標準,例如應用XSLT來調整格式,因此它們可以被反序列化? – StuartLC

+0

您需要將XML的摘要與其使用量分開。您的表示層需要擺脫關注使用XML來填充它的業務。 – dbugger

+0

如果項目只是添加或刪除你應該能夠使用相同的類,但由於你正在改變節點內的位置,你需要實現[IXmlSerializable](http://www.codeproject.com/Articles/43237/How-to-Implement-IXmlSerializable-正確)並根據版本進行讀取。 – SwDevMan81

回答

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

你好 - 非常感謝你的回答和代碼片段。我會試一試,然後回到報告結果。 BR,Albert – Albert