4

XMLをオブジェクトに逆シリアル化しようとしていますが、1つの状況でスタックしています。誰かがここで私を助けてくれませんか。

XML:

<?xml version="1.0" ?>
<Level>
  <Warp_Blocks>
        <Warp_Block>
            <Block row="7" col="7" />
            <Block row="2" col="7" />
        </Warp_Block>
        <Warp_Block>
            <Block row="4" col="4" />
            <Block row="3" col="7" />
        </Warp_Block>
  </Warp_Blocks>
</Level>

コード:

  [XmlRoot("Level")]
   public class LData
    {
        [XmlArray("Warp_Blocks")]
        [XmlArrayItem("Warp_Block",typeof(WarpBlock),IsNullable = false)]
        public List<WarpBlock> WarpBlocks;
    }
   public class LBlock
   {
      [XmlAttribute("row")]
      public int row;
      [XmlAttribute("col")]
      public int col;
   }
   public class WarpBlock
   {
      [XmlArray("Warp_Block")]
      [XmlArrayItem("Block",typeof(LBlock),IsNullable= false)]
      public List<LBlock> WarpBlocks;

      public WarpBlock()
      {
            WarpBlocks = new List<LBlock>();
      }
   }

1つのレベルに逆シリアル化できます。つまり、アイテムのリストオブジェクトを取得しますが、個々のアイテムオブジェクトにはブロックオブジェクトのリストが含まれていません。私はここで何が間違っているのですか?

4

2 に答える 2

4

LData クラスを次のように変更します。

[XmlRoot("Level")]
public class LData
{
    [XmlElement("Warp_Blocks")]
    public List<WarpBlock> WarpBlocks;
}

編集:
2 番目の Warp_Block を読み取らない理由がわかりません。考えられる唯一の理由は、質問に投稿したこと以外のことをしているということです。完全な例は次のとおりです。

[XmlRoot("Level")]
public class LData
{
    [XmlElement("Warp_Blocks")]
    public List<WarpBlock> WarpBlocks;
}
public class LBlock
{
    [XmlAttribute("row")]
    public int row;
    [XmlAttribute("col")]
    public int col;
}
public class WarpBlock
{
    [XmlArray("Warp_Block")]
    [XmlArrayItem("Block", typeof(LBlock), IsNullable = false)]
    public List<LBlock> WarpBlocks;

    public WarpBlock()
    {
        WarpBlocks = new List<LBlock>();
    }
}
public class Program
{
    public static void Main()
    {
        string test =
            "<?xml version=\"1.0\" ?>" +
            "<Level>" +
            "  <Warp_Blocks>" +
            "        <Warp_Block>" +
            "            <Block row=\"7\" col=\"7\" />" +
            "            <Block row=\"2\" col=\"7\" />" +
            "        </Warp_Block>" +
            "        <Warp_Block>" +
            "            <Block row=\"4\" col=\"4\" />" +
            "            <Block row=\"3\" col=\"7\" />" +
            "        </Warp_Block>" +
            "  </Warp_Blocks>" +
            "</Level>";

        byte[] byteArray = Encoding.ASCII.GetBytes(test);
        MemoryStream stream = new MemoryStream(byteArray);

        XmlSerializer s = new XmlSerializer(typeof (LData));
        LData data = (LData) s.Deserialize(stream);

        foreach (var a in data.WarpBlocks)
            foreach (var b in a.WarpBlocks)
                Console.WriteLine(b.row + ", " + b.col);

        Console.ReadKey();
    }
}

これは正しく出力されます:

7, 7
2, 7
4, 4
3, 7
于 2011-02-16T13:46:06.437 に答える
0

ここで何をしているのか正確にはわかりませんが、デシリアライゼーションには落とし穴があります (少なくともバイナリ デシリアライゼーション。わかりませんが、XML シリアライゼーションでも同じだと思います)。aList<T>または aを逆シリアル化すると、逆シリアル化コンストラクターが終了するまでDictionary<S,T>、リストにnull値 (値型の場合は既定値) が入力されます。コンストラクターを終了した後にのみ、実際の逆シリアル化された s で満たされたリストが表示されTます。

これは、リストで何かをしたい場合、コンストラクターでは実行できないことを意味します。[OnDeserializedAttribute]代わりに、リストで実行する必要がある作業を含むメソッドを作成できます。属性で注釈が付けられている限り、リストがいっぱいになった、逆シリアル化が戻る前に呼び出されます。メソッドには任意の名前を付けることができます。

詳細については、 MSDNを参照してください。

于 2011-02-16T13:01:52.540 に答える