2017-01-23 9 views
0

私は、次のような構造を持つクラスのセットがあります。プラン>要素>一覧を<要素>逆シリアル化のXML

[Serializable, XmlRoot("Plan")] 
public class Plan 
{ 
    public Plan() 
    { 
     elements = new Elements(); 
    } 

    public int floor {get; set}; 

    [XmlElement("elements")] 
    public Elements elements { get; set; } 
} 

[Serializable, XmlType("elements")] 
public class Elements 
{ 
    public Elements() { Items = new List<Element>(); } 
    [XmlElement("element")] 
    public List<Element> Items { get; set; } 
} 

[Serializable] 
public class Element 
{ 
    public int id { get; set; } 
} 

このすべては、このXMLにSystem.Xml.Serializationを用いて微細なシリアライズ:

<?xml version="1.0"?> 
<Plan xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <elements> 
    <element> 
     <id>0</id> 
    </element> 
    </elements> 
</Plan> 

しかし、私は再びそれをデシリアライズしようとすると、要素のクラスが全く読み込まれないとSerialize-後の結果が> Deserialize->のSerialize手順は、次のようになります。

<?xml version="1.0"?> 
<Plan xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <floor>0</floor> 
    <elements /> 
</Plan> 

これは私のデシリアライズ機能である:

public class Program { 
    public Plan plan; 

    public static void deserializeXml<T>(this T toDeserialize, string filename) 
    { 
     XmlSerializer xmlSerializer = new XmlSerializer(toDeserialize.GetType()); 

     Stream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read); 
     toDeserialize = (T) xmlSerializer.Deserialize(stream); 
    } 

    public void loadXml() { 
     deserializeXml(plan, "plan.xml"); 
    } 
} 

は、誰かが私に、これは動作しませんなぜ手掛かりを与えることができますか?ありがとう!

+0

[ask]と[mcve]をお読みください。おそらく 'SerializeXml()'または 'DeserializeXml()'に不正な 'T'を渡しているでしょう。特にどこにも出現しない 'floor'要素は、それに向けて示唆されているようです。 – CodeCaster

+0

「フロア」とは何ですか?私はまた、あなたがここに示している以上にあなたがやっていると思っています。 – HimBromBeere

+0

'floor'は私の最小限の例では欠けていた' Plan'のプロパティです。私は今例を完成させるために自分の投稿を更新しました。 – farbro

答えて

0

私は直列化自体には何の関係もない軽微な変更で作業するあなたのコードを持って、それ故に問題はXMLシリアル化自体ではなく、それが呼ばれる方法であるように見えるしません:

public static void deserializeXml<T>(this T toDeserialize, string filename) 
{ 
    // !!!! toDeserialize is a copy to instance in the heap, so -> ... 

    XmlSerializer xmlSerializer = new XmlSerializer(toDeserialize.GetType()); 

    Stream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read); 
    // -> ... here we assign reference of deserialized instance to toDeserialize(which is a copy) 
    toDeserialize = (T) xmlSerializer.Deserialize(stream); 

    // we need to return result here, otherwise this reference copy will be left dying here 
} 

コード:だから、次の方法でそれを実行している

static class Serializer 
{ 
    // note here: deserializeXml returns reference to deserialized instance 
    public static T deserializeXml<T>(string filename) 
    { 
     XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); 

     using (Stream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) 
     { 
      var toDeserialize = (T)xmlSerializer.Deserialize(stream); 
      return toDeserialize; 
     } 
    } 

    public static void serializeToXml<T>(T instance, string filename) 
    { 
     var xmlSerializer = new XmlSerializer(instance.GetType()); 
     using (Stream stream = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) 
     { 
      xmlSerializer.Serialize(stream, instance); 
     } 
    } 
} 

Plan p = new Plan(); 
    p.elements.Items.Add(new Element { id = 1 }); 
    p.elements.Items.Add(new Element { id = 2 }); 
    p.elements.Items.Add(new Element { id = 3 }); 

    Serializer.serializeToXml(p, @"D:\1.xml"); 
    var p2 = Serializer.deserializeXml<Plan>(@"D:\1.xml"); 
    Console.WriteLine(p2.elements.Items.Count); 
    Serializer.serializeToXml(p2, @"D:\2.xml"); 

グラム最後にはD:\1.xmlD:\2.xmlと同じです。 これが役に立ちますようにお願いします。

+0

あなたは絶対に正しいです!私は、新しい非直列化Planオブジェクトを割り当てたことはありません。ありがとうございました! – farbro