Deserialize List<ArrayList> object
I am trying to de-serialize a XML to object but I am getting stuck at one situation. Can anyone please help me out here.
XML:
<?xml version="1.0" ?>
<Level>
<Warp_Blocks>
<Warp_Block>
<Block row="7" col="7" />
<Block row="2" col="7" />
</Warp_Block>
<Warp_Block>
开发者_如何学Go <Block row="4" col="4" />
<Block row="3" col="7" />
</Warp_Block>
</Warp_Blocks>
</Level>
Code:
[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>();
}
}
I am able to de-serialize to one level i.e. I get a List of Item objects but the individual Item objects don't contain the List of Block objects. What am I doing wrong here?
Change your LData class to this:
[XmlRoot("Level")]
public class LData
{
[XmlElement("Warp_Blocks")]
public List<WarpBlock> WarpBlocks;
}
EDIT:
I don't know why it is not reading your second Warp_Block. The only possible reason I think can be that you are doing something else than what you have posted in the question. Here is the full example:
[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();
}
}
It correctly outputs this:
7, 7
2, 7
4, 4
3, 7
I don't know exactly what you are doing here, but there is a gotcha with deserialization (at least binary deserialization. I don't know, but I suspect that it is the same for XML serialization). On deserializing a List<T>
or a Dictionary<S,T>
, the list is filled with null
values (or default value if it is a value type) until the deserialization constructor has been exited. Only after exiting the constructor is the list filled with the actual, deserialized T
s.
This means that if you want to do something with the list, it cannot be done in the constructor. You can instead make a method which contains any work which needs to be done with the list, and as long as it is annotated with the [OnDeserializedAttribute]
attribute, it will be called after the list has been filled but before the deserialization returns. The method can have any name.
See MSDN for details.
精彩评论