2017-04-05 14 views
1

ネストクラスのメンバー全体をシリアル化せずにネストしたクラスをシリアル化する最良の方法を試しています。クラス以下を仮定:ネストしたクラスメンバーのシリアル化

public class ClassA 
{ 
    public decimal ID { get; set; } 
} 

public class ClassA1 : ClassA 
{ 
    public decimal Name { get; set; } 
    public decimal Value { get; set; } 
    public decimal Description { get; set; } 
} 

public class ClassA2 : ClassA 
{ 
    public ClassA1 Details { get; set; } 
    public int SomeValue { get; set; } 
} 

私はList型の変数に格納されているタイプのClassA1のオブジェクトの固定されたリストを持っています。

私もList型の変数

に格納されているタイプのClassA2のオブジェクトのリストを持っている私は何をしたいのシリアライズとClassA2オブジェクトの私のリストをデシリアライズです。自動直列化は各ClassA1オブジェクトの内容全体をシリアル化しますが、直列化してからClassA1.IDメンバを逆シリアル化して、逆シリアル化時に固定リストからオブジェクト参照を取得したいだけです。

自動シリアライズは私にこれを与える:私は私のXMLにしたい

... 
<ClassA2> 
    <ID>IDStringForObjectClassA2</ID> 
    <Details> 
    <ClassA1> 
     <ID>IDStringForObjectOfClassA1</ID> 
     <Name>MyNameValue</Name> 
     <Value>MyStringValue</Value> 
     <Description>MyDescriptionValue</Description> 
    </ClassA1> 
    </Details> 
    <SomeValue>0</SomeValue> 
</ClassA2> 

最終的な結果は、私が欲しい、この

... 
<ClassA2> 
    <ID>IDStringForObjectClassA2</ID> 
    <Details> 
    <ClassA1> 
     <ID>IDStringForObjectOfClassA1</ID> 
    </ClassA1> 
    </Details> 
    <SomeValue>0</SomeValue> 
</ClassA2> 

とClassA1.IDメンバーの逆シリアル化の上にあります予めロードされたリスト内の実際のオブジェクトを見つけるため

EDIT:ドキュメントs

public class Document 
{ 
    private _ClassA2; 

    public Document() { _ClassA2 = null; } 

    public ClassA2 ClassA2 
    { 
    get { return _ClassA2; } 
    set { _ClassA2 = value; } 
    } 

    public string Serialize(StreamWriter writer) 
    { 
    var serializer = new XmlSerializer(typeof(ClassA2)); 
    serializer.Serialize(writer, this); 
    return writer.ToString(); 
    } 

    public static ClassA2 DeSerialize(StreamReader reader) 
    { 
    var serializer = new XmlSerializer(typeof(ClassA2)); 
    ClassA2 value = serializer.Deserialize(reader) as ClassA2 ; 
    return value; 
    } 
} 
+0

デシリアライズに使用している現在のコードは何ですか? – RBT

+0

あなたのXMLは、あなたが言及したクラスに従って非直列化には無効です。 'Details'タグの中に' ClassA1'タグがあります。 'ClassA2'の終了タグもありません。私は をデシリアライズするために、標準のXmlSerializerクラスを使用しています – RBT

+0

@RBTは、このに上記を組み込むことがとにかくありますか私は完全にカスタム直列化復元に変更しなければならないの 'VARシリアライザ=新しいXmlSerializerを(typeof演算(CableDocument));' 'CableDocument value =シリアライザ。' 編集:私の人生のために、正しくマークダウンを得ることができませんでした。 – Woodjitsu

答えて

2

以下erializerクラスを使用すると、データと同じクラスに「ShouldSerialize」メソッドを定義するか、要素を除外するには:

public bool ShouldSerializeDescription() 
{ 
    return false; 
} 

public decimal Description { get; set; } 

または財産上[XmlIgnore]属性を使用します。

[XmlIgnore] 
public decimal Description { get; set; } 

ほとんどの場合、XmlIgnoreをおすすめします。

メンバーを配置してフィールドに入力することについては、私が知っている限りこれを達成するためのものはありません。ループするだけで値を手動で見つける必要があります。詳細については、this postを参照してください。

+0

John、 XmlIgnoreまたはShouldSerializeを使用する理由は、ClassA1が個別にシリアル化され、これらのフィールドがシリアル化されている必要があるためです。私が持っている問題は、ネストされたクラスを含むクラスを直列化するときです。 メインクラス(ClassA2)は、ネストされたクラスを参照するメンバ変数が適切なClassA1オブジェクトを個別に逆シリアル化されたオブジェクトのリストで参照できるように、IDをシリアル化およびデシリアライズする必要があります。 – Woodjitsu

+1

提供されたリンクは、私が達成しようとしているものを参照しているようですので、そのスレッドで提供されているオプションも見ていきます。 – Woodjitsu

1

シリアル化されている入力XMlを有効なXMLに変更しました。 IDのプロパティをClassA1にデシリアライズするコードは、Detailsプロパティにあります。コードファイルの先頭に次のインポートusing System.Xml.Linq;を使用する必要があります。

private static void NestedMemberSerialization() 
{ 

    var serializedXml = "<ClassA2><ID>1</ID><Details><ClassA1><ID>2</ID><Name>4</Name><Value>2</Value><Description>3</Description></ClassA1></Details><SomeValue>2</SomeValue></ClassA2>"; 

    XDocument doc = XDocument.Parse(serializedXml); 

    var mySteps = (from s in doc.Descendants("ClassA2") 
        select new ClassA2 
        { 
         ID = decimal.Parse(s.Element("ID").Value), 
         SomeValue = int.Parse(s.Element("SomeValue").Value), 
         Details = new ClassA1 { ID = decimal.Parse(s.Element("Details").Descendants("ClassA1").Descendants("ID").ElementAt(0).Value) } 
        }).ToList(); 

} 
関連する問題