2012-02-14 11 views
2

シリアライズとデシリアライズするプログラムを作成しました。これはうまくいきます(サブクラスで正しく実装すると、それを実装する予定です)。しかし、Foreachを使用して結果を繰り返し処理できるようにしたいと思ったとき、私は問題に遭遇しました。IEnumeratorを実装するクラスのシリアライゼーション

これが機能しなかった後、私はIEnumeratorIEnumerableインターフェイスを実装し、必要なメソッドをクラスに追加する必要があることを知りました。だから、私は自分のコレクションをループすることができます。

私は二つのことを結合しようとすると、問題が始まる...

私はもともと、このエラーましシリアライズ:

インナー: {"The type ThereIsOnlyRules.Army was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically."}

は私が防ぐために、私のクラスに[XmlInclude(typeof(Employee))]を追加しますこの例外は今では最初の2つのルート要素は<ArmyListing><Army>の代わりに<ArrayofAnyType><AnyType>と呼ばれます。私は何らかの理由で[XmlRoot("whatever")]を戻す方法を理解できません。

私はこのエラーを取得する{"There is an error in XML document (0, 0)."} インナーデシリアライズするとき:{"Root element is missing."}

を私が検索しました - しかし、このエラーは、多くの異なる方法で生成することができるように思えます。私は自分のコードに適用される解決策は見つけられませんでした(私が知る限り)。

私はこれらの問題の原因や解決策に関する情報を感謝しています。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml.Serialization; 
using System.Runtime.Serialization; 
using System.IO; 
using System.Collections; 

namespace ThereIsOnlyRules 
{ 
[XmlInclude(typeof(Army))] 
public class ArmyListing : IEnumerator, IEnumerable 
{ 

    // Fields 
    private List<Army> _army; 

    // Properties 
    [XmlArray("army-category")] 
    public List<Army> Army 
    { 
     get { return _army; } 
     set { _army = value; } 
    } 

    // Public Methods 
    public void SerializeToXML(ArmyListing armyListing) 
    { 
     try 
     { 
      //armyListing.army.Add(army); 

      XmlSerializer serializer = new XmlSerializer(typeof(ArmyListing)); 
      //XmlSerializer serializer = new XmlSerializer(typeof(ArmyListing), new Type[] { typeof(ArmyListing) }); 
      TextWriter textWriter = new StreamWriter(@"C:\Test\40k.xml"); 
      serializer.Serialize(textWriter, armyListing); 
      textWriter.Close(); 
     } 
     catch (Exception ex) { } 
    } 

    #region IEnumerator/IEnumerable req methods 
    [XmlIgnore] 
    private int position = -1; 
    //enumerator & ienumerable 
    public IEnumerator GetEnumerator() 
    { 
     return (IEnumerator)this; 
    } 

    //enumerator 
    public bool MoveNext() 
    { 
     position++; 
     return (position < Army.Count); 
    } 

    //ienumerable 
    public void Reset() 
    { 
     position = 0; 
    } 
    [XmlIgnore] 
    public object Current 
    { 
     get { return Army[position]; } 
    } 

    // Added to prevent Exception 
    // To be XML serializable, types which inherit from IEnumerable must have an implementation of Add(System.Object) 
    //at all levels of their inheritance hierarchy. ThereIsOnlyRules.ArmyListing does not implement Add(System.Object). 
    public void Add(Object fix) 
    { } 
    #endregion 
} 

[Serializable] 
public class Army// : IEnumerator, IEnumerable 
{ 
    // Fields 
    private List<UnitCategory> _unitCategory; 
    private string _armyName; 

    // Properties 
    [XmlArray("unit-category")] 
    public List<UnitCategory> UnitCategory 
    { 
     get { return _unitCategory; } 
     set { _unitCategory = value; } 
    } 

    [XmlAttribute("name")] 
    public string ArmyName 
    { 
     get { return _armyName; } 
     set { _armyName = value; } 
    } 

    //#region IEnumerator/IEnumerable req methods 
    //private int position = -1; 
    ////enumerator & ienumerable 
    //public IEnumerator GetEnumerator() 
    //{ 
    // return (IEnumerator)this; 
    //} 

    ////enumerator 
    //public bool MoveNext() 
    //{ 
    // position++; 
    // return (position < UnitCategory.Count); 
    //} 

    ////ienumerable 
    //public void Reset() 
    //{ 
    // position = 0; 
    //} 
    //public object Current 
    //{ 
    // get { return UnitCategory[position]; } 
    //} 
    //public void Add(Object Army) 
    //{ } 
    //#endregion 
} 

[Serializable] 
public class UnitCategory// : IEnumerator, IEnumerable 
{ 
    // Fields 
    private List<UnitType> _unitType; 
    private string _unitCategoryName; 

    // Properties 
    [XmlArray("unit-type")] 
    public List<UnitType> UnitType 
    { 
     get { return _unitType; } 
     set { _unitType = value; } 
    } 

    [XmlAttribute("name")] 
    public string UnitCategoryName 
    { 
     get { return _unitCategoryName; } 
     set { _unitCategoryName = value; } 
    } 

    //#region IEnumerator/IEnumerable req methods 
    //private int position = -1; 
    ////enumerator & ienumerable 
    //public IEnumerator GetEnumerator() 
    //{ 
    // return (IEnumerator)this; 
    //} 

    ////enumerator 
    //public bool MoveNext() 
    //{ 
    // position++; 
    // return (position < UnitType.Count); 
    //} 

    ////ienumerable 
    //public void Reset() 
    //{ 
    // position = 0; 
    //} 
    //public object Current 
    //{ 
    // get { return UnitType[position]; } 
    //} 
    //public void Add(Object Army) 
    //{ } 
    //#endregion 
} 

[Serializable] 
public class UnitType// : IEnumerator, IEnumerable 
{ 
    // Fields 
    private List<Unit> _unit; 
    private string _unitTypeName; 

    //Properties 
    [XmlArray("unit")] 
    public List<Unit> Unit 
    { 
     get { return _unit; } 
     set { _unit = value; } 
    } 

    [XmlAttribute("name")] 
    public string UnitTypeName 
    { 
     get { return _unitTypeName; } 
     set { _unitTypeName = value; } 
    } 

    //#region IEnumerator/IEnumerable req methods 
    //private int position = -1; 

    ////enumerator & ienumerable 
    //public IEnumerator GetEnumerator() 
    //{ 
    // return (IEnumerator)this; 
    //} 

    ////enumerator 
    //public bool MoveNext() 
    //{ 
    // position++; 
    // return (position < Unit.Count); 
    //} 

    ////ienumerable 
    //public void Reset() 
    //{ 
    // position = 0; 
    //} 
    //public object Current 
    //{ 
    // get { return Unit[position]; } 
    //} 

    //public void Add(Object Army) 
    //{ } 
    //#endregion 
} 

[Serializable] 
public class Unit 
{ 
    // Fields 
    private string _unitName; 
    private string _composition; 
    private string _weaponSkill; 
    private string _ballisticSkill; 
    private string _strength; 
    private string _initiative; 
    private string _toughness; 
    private string _wounds; 
    private string _attacks; 
    private string _leadership; 
    private string _savingThrow; 
    private string _specialRules; 
    private string _dedicatedTransport; 
    private string _options; 
    private string _armour; 
    private string _weapons; 

    // Properties 
    [XmlAttribute("name")] 
    public string UnitName 
    { 
     get { return _unitName; } 
     set { _unitName = value; } 
    } 

    [XmlAttribute("composition")] 
    public string Composition 
    { 
     get { return _composition; } 
     set { _composition = value; } 
    } 

    [XmlAttribute("weapon-skill")] 
    public string WeaponSkill 
    { 
     get { return _weaponSkill; } 
     set { _weaponSkill = value; } 
    } 

    [XmlAttribute("ballistic-skill")] 
    public string BallisticSkill 
    { 
     get { return _ballisticSkill; } 
     set { _ballisticSkill = value; } 
    } 

    [XmlAttribute("strength")] 
    public string Strength 
    { 
     get { return _strength; } 
     set { _strength = value; } 
    } 

    [XmlAttribute("toughness")] 
    public string Toughness 
    { 
     get { return _toughness; } 
     set { _toughness = value; } 
    } 

    [XmlAttribute("wounds")] 
    public string Wounds 
    { 
     get { return _wounds; } 
     set { _wounds = value; } 
    } 

    [XmlAttribute("initiative")] 
    public string Initiative 
    { 
     get { return _initiative; } 
     set { _initiative = value; } 
    } 

    [XmlAttribute("attacks")] 
    public string Attacks 
    { 
     get { return _attacks; } 
     set { _attacks = value; } 
    } 

    [XmlAttribute("leadership")] 
    public string Leadership 
    { 
     get { return _leadership; } 
     set { _leadership = value; } 
    } 

    [XmlAttribute("saving-throw")] 
    public string SaveThrow 
    { 
     get { return _savingThrow; } 
     set { _savingThrow = value; } 
    } 

    [XmlAttribute("armour")] 
    public string Armour 
    { 
     get { return _armour; } 
     set { _armour = value; } 
    } 

    [XmlAttribute("weapons")] 
    public string Weapons 
    { 
     get { return _weapons; } 
     set { _weapons = value; } 
    } 

    [XmlAttribute("special-rules")] 
    public string SpecialRules 
    { 
     get { return _specialRules; } 
     set { _specialRules = value; } 
    } 

    [XmlAttribute("dedicated-transport")] 
    public string DedicatedTransport 
    { 
     get { return _dedicatedTransport; } 
     set { _dedicatedTransport = value; } 
    } 

    [XmlAttribute("options")] 
    public string Options 
    { 
     get { return _options; } 
     set { _options = value; } 
    } 
} 
} 

私は、あなたがXmlIncludeを使用する必要はありません、のIEnumerator、IEnumerableを実装するのを削除したフォーム

using System; 
using System.Windows.Forms; 
using System.Collections.Generic; 
using System.Xml.Serialization; 
using System.IO; 

namespace ThereIsOnlyRules 
{ 
public partial class Form1 : Form 
{ 
    ArmyListing armyListing; 
    ArmyListing XmlListing = new ArmyListing(); 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     SerializeArmyListings(); 
    } 

    public static void SerializeArmyListings() 
    { 
     UnitCategory troopsCategory = new UnitCategory 
     { 
      UnitCategoryName = "Troops", 
      UnitType = new List<UnitType> 
      { 
       new UnitType 
        { 
         UnitTypeName = "Infantry", 
         Unit = new List<Unit> 
          { 
           new Unit 
            { 
             Armour = "Chitin", 
             Attacks = "3", 
             BallisticSkill = "100", 
             Composition = "20", 
             DedicatedTransport = "No", 
             Initiative = "3", 
             Leadership = "5", 
             Options = "8", 
             SaveThrow = "6+", 
             SpecialRules = "None", 
             Strength = "3", 
             Toughness = "4", 
             UnitName = "Hornmagant", 
             Weapons = "Many", 
             WeaponSkill = "3", 
             Wounds = "1"            
            } 
          } 
        } 
      } 
     }; 

     Army army = new Army 
     { 
      ArmyName = "Tyranid", 
      UnitCategory = new List<UnitCategory> 
     { 
      troopsCategory 
     } 
     }; 

     ArmyListing armyListing = new ArmyListing 
     { 
      Army = new List<Army> 
      { 
       army 
      } 
     }; 

     armyListing.SerializeToXML(armyListing);// SerializeToXml(armyListing); 
    } 

    public ArmyListing DeserializeXml() 
    { 

     string path = @"C:\Test\40k.xml"; 

     XmlSerializer serializer = new XmlSerializer(typeof(ArmyListing)); 
     //XmlSerializer serializer = new XmlSerializer(typeof(ArmyListing), new Type[] { typeof(ArmyListing) }); 


     StreamReader reader = new StreamReader(path); 

     XmlListing = (ArmyListing)serializer.Deserialize(reader); 
     reader.Close(); 

     return XmlListing; 

    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     DeserializeXml(); 

     ////test 
     //foreach (var list in armyListing) 
     //{ 
     // listBox1.DataSource = list; 
     //} 

     int xmlcount = XmlListing.Army.Count; 
    } 

} 
} 
+0

は、[編集]を見ていてください:私が提案する何

はIEnumerableを実装することで、IEnumeratorを 後は、私のテストコードです。 – findcaiyzh

答えて

1

出力xmlは、次にデシリアライズすることができます。

<?xml version="1.0" encoding="utf-8"?> 
<ArmyListing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <army-category> 
    <Army name="Tyranid"> 
     <unit-category> 
     <UnitCategory name="Troops"> 
      <unit-type> 
      <UnitType name="Infantry"> 
       <unit> 
       <Unit name="Hornmagant" composition="20" weapon-skill="3" ballistic-skill="100" strength="3" toughness="4" wounds="1" initiative="3" attacks="3" leadership="5" saving-throw="6+" armour="Chitin" weapons="Many" special-rules="None" dedicated-transport="No" options="8" /> 
       </unit> 
      </UnitType> 
      </unit-type> 
     </UnitCategory> 
     </unit-category> 
    </Army> 
    </army-category> 
</ArmyListing> 

編集: クラスはIEnumerableをとのIEnumeratorを実装する場合、私は推測します。 XmlSerialerはそれを列挙するために使用します。オブジェクトのCurrent {}プロパティが原因で型が失われました。そうAnytypeは示す。私の答えの一部:

public class ArmyListing : IEnumerable<Army>, IEnumerator<Army> 
{ 

    // Fields 
    private List<Army> _army; 

    // Properties 
    [XmlArray("army-category")]   
    public List<Army> Army 
    { 
     get { return _army; } 
     set { _army = value; } 
    } 

    // Public Methods 
    public void SerializeToXML(ArmyListing armyListing) 
    { 
     try 
     { 
      //armyListing.army.Add(army); 

      XmlSerializer serializer = new XmlSerializer(typeof(ArmyListing)); 
      //XmlSerializer serializer = new XmlSerializer(typeof(ArmyListing), new Type[] { typeof(ArmyListing) }); 
      TextWriter textWriter = new StreamWriter(@"C:\Temp\40k.xml"); 
      serializer.Serialize(textWriter, armyListing); 
      textWriter.Close(); 
     } 
     catch (Exception ex) { } 
    } 

    #region IEnumerator/IEnumerable req methods 
    [XmlIgnore] 
    private int position = -1; 


    // Added to prevent Exception 
    // To be XML serializable, types which inherit from IEnumerable must have an implementation of Add(System.Object) 
    //at all levels of their inheritance hierarchy. ThereIsOnlyRules.ArmyListing does not implement Add(System.Object). 

    public void Add(Army fix) 
    { 
     if (_army == null) 
      _army = new List<Army>(); 

     _army.Add(fix); 
    } 
    #endregion    

    public IEnumerator<Army> GetEnumerator() 
    { 
     return this; 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return this; 
    } 

    [XmlIgnore] 
    public Army Current 
    { 
     get { return _army[position]; } 

    } 

    public void Dispose() 
    { 

    } 

    [XmlIgnore] 
    object IEnumerator.Current 
    { 
     get { return _army[position]; } 
    } 

    public bool MoveNext() 
    { 
     position++; 
     return (position < Army.Count); 
    } 

    public void Reset() 
    { 
     position = 0; 
    } 
} 
+0

シリアル化が機能することを確認できますが、逆シリアル化を試みるとNullReferenceExceptionがスローされます。返されるオブジェクトには値が設定されません。カウントは0で、現在の値はnullExceptionをスローします。 CurrentのXmlIgnoreタグを試してみました。 – Amicable

+0

メソッドを追加することが重要です、私の改訂公開空の追加(軍の修正)の実装を参照してください – findcaiyzh

+0

ああ、私の悪い。私はあなたがAddメソッドのタイプを変更したことに気付きました。私は変更を実装しました。すべての作業! 多くのおかげで:) – Amicable

関連する問題