2012-02-20 12 views
9

現在のXmlSerializerは、次のような構造を生成します。のXmlSerializerはXSIを置き換える:タイプ名をノードに

<config> 
    <BaseType xsi:type="DerivedType1" /> 
    <BaseType xsi:type="DerivedType2" /> 
</config> 

は、それがノードに型名を置くようにする方法はあります:

<config> 
    <DerivedType1 /> 
    <DerivedType2 /> 
</config> 

+0

あなたがシリアライズするクラスのコードを提供することができますか? – Seb

答えて

0

まあ、要素名をXmlElement属性でオーバーライドできます。

[XmlElement("DerivedType1")] 
public BaseType : DerivedType1 {get;set;} 

場合は、まだXSIを置く:あなたのクラスはどんな感じに見えるんけれどもで入力して、さらに大きな混乱を生成...

+0

要素名を上書きしたくありません。私は、シリアライザがクラス名 – SiberianGuy

+0

と等しい名前を設定したいと思っています。これは、この回答の意図です。 – Seb

+1

それはそうするでしょう。私が知っている限り、タイピングを抑止することはできません。なぜなら、あなたはデシリアライズできないからです。デシリアライズする必要がない場合は、シリアル化していないので、シリアライズをやめて、クラスのdumptoxmlメソッドを記述するだけです。シリアライズにはルールがありますが、それに従わない場合は実行していません... –

24

XmlElementAttributeコンストラクタオーバーロード(string elementName, Type type)を使用してください。 メンバー内の実際の型を指定して、要素名を置き換えることができます。 複数の派生型がある場合は、これらの複数をスタックします。

List<Base>のようなインスタンスが含まれている可能性のある汎用コレクションをシリアル化しようとする場合は、同じ方法でXmlArrayItemを使用してください。人々はあなたができることは決してないだろう」と言っておくのはなぜ

[XmlRoot] 
public class Data 
{ 
    [XmlElement("Derived1", typeof(Derived1))] 
    [XmlElement("Derived2", typeof(Derived2))] 
    public Base foo { get; set; } 
    [XmlArrayItem("Derived1", typeof(Derived1))] 
    [XmlArrayItem("Derived2", typeof(Derived2))] 
    public List<Base> fooList { get; set; } 
} 

public class Base { ... } 
public class Derived1 : Base { ... } 
public class Derived2 : Base { ... } 
0

:この方法で定義する

も暗黙的にXmlInclude属性が

サンプル定義を必要とされていない、知られている派生型を作りますデシリアライズする。 " これは、定義上は偽です。

public class BaseClass { 
    public string Name {get;set;} 
} 
[XmlRoot("BaseClass")] 
public class ChildClass : BaseClass { 
    public int Value {get;set;} 
} 
[XmlRoot("BaseClass")] 
public class FlatClass 
{ 
    public string Name {get;set;} 
    public int Value {get;set;} 
} 

XmlSerializer ser1 = new XmlSerializer(typeof(BaseClass)); 
XmlSerializer ser2 = new XmlSerializer(typeof(ChildClass)); 
XmlSerializer ser3 = new XmlSerializer(typeof(FlatClass)); 
ser1.Serialize(File.Open("ser1.xml", FileMode.Create), new BaseClass(){Name="Base"}); 
ser2.Serialize(File.Open("ser2.xml", FileMode.Create), new ChildClass(){Name="Child",Value = 1}); 

ser1.Deserialize(File.OpenRead("ser2.xml")); 
ser2.Deserialize(File.OpenRead("ser1.xml")); 
ser3.Deserialize(File.OpenRead("ser2.xml")); 

ブーム。作品はちょうど罰金!!!!! シリアライゼーションは、3つの方法で完全に完全になります。結果のオブジェクトはいずれの側でも100%ではないかもしれませんが、逆直列化しています。 デシリアライズser2.xml SER2はser1.xml

をデシリアライズするとき、このモデルを壊すだけの事はある値propertuyをスキップするときSER1は、Value要素を無視します:

ser1.Serailize(File.Open("ser3.xml", FileMode.Create), new ChildClass(){Name = "Child2", Value = 2}); 
XmlSerialize ser3 = new XmlSerializer(typeof(FlatClass)); 
ser3.Deserialize(File.OpenRead("ser3.xml")); 

この最後の休憩、シリアライザbecuase BaseClassは要素のxsi:type = "ChildClass"属性を含むスキーマ標準に従います(ただし、必要な時間の99%は貴重です)。 Ser3はそのタイプには対応していないため、特にFlatClassがWANまたはLAN回線を介して別のアセンブリに存在する場合は、そのタイプを処理できません。 Honey-badgerと同じように、XmlSerailizerは要素や値を見つけることができ、スキーマ内の何もプロセスを中断しない限り、要素や値については気にしません。 XSI:TYPE属性は、スキーマを中断します。

たとえば、サービスにFlatClassというクラスがある場合、WCFまたは他のXML通信ベースのシステムを使用する場合、xsi:type = ""属性を含むChildClassをDESERIALIZEしません。ただし、シリアライザをBaseClassに使用しない場合は、xsi:type属性を使用しないで、まったく同じXMLを逆シリアル化します。

Q.E.D. 多くの場合、時間が有益で、必要であり、理想的です。には、にxsi:type属性が含まれています。

したがって、XmlSerializerをBaseClass型用に作成し、子型をシリアル化するときにxsi:type属性を含めないように指示する方法がありますか?

おかげ Jaeden "SIFO Dyas" al'Raec Ruiner

関連する問題